Commit b0260212 authored by whesse@chromium.org's avatar whesse@chromium.org

Stop "cooking" targets of jumps and calls in code objects. Do not convert...

Stop "cooking" targets of jumps and calls in code objects.  Do not convert jump and call targets to absolute pointers to Code objects during GC, heap verification, and serialization.
Review URL: http://codereview.chromium.org/203070

git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@2941 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
parent 7febdab8
...@@ -637,15 +637,7 @@ static void VerifyNonPointerSpacePointers() { ...@@ -637,15 +637,7 @@ static void VerifyNonPointerSpacePointers() {
HeapObjectIterator code_it(Heap::code_space()); HeapObjectIterator code_it(Heap::code_space());
while (code_it.has_next()) { while (code_it.has_next()) {
HeapObject* object = code_it.next(); HeapObject* object = code_it.next();
if (object->IsCode()) { object->Iterate(&v);
Code::cast(object)->ConvertICTargetsFromAddressToObject();
object->Iterate(&v);
Code::cast(object)->ConvertICTargetsFromObjectToAddress();
} else {
// If we find non-code objects in code space (e.g., free list
// nodes) we want to verify them as well.
object->Iterate(&v);
}
} }
HeapObjectIterator data_it(Heap::old_data_space()); HeapObjectIterator data_it(Heap::old_data_space());
...@@ -1935,7 +1927,6 @@ Object* Heap::CreateCode(const CodeDesc& desc, ...@@ -1935,7 +1927,6 @@ Object* Heap::CreateCode(const CodeDesc& desc,
code->set_relocation_size(desc.reloc_size); code->set_relocation_size(desc.reloc_size);
code->set_sinfo_size(sinfo_size); code->set_sinfo_size(sinfo_size);
code->set_flags(flags); code->set_flags(flags);
code->set_ic_flag(Code::IC_TARGET_IS_ADDRESS);
// Allow self references to created code object by patching the handle to // Allow self references to created code object by patching the handle to
// point to the newly allocated Code object. // point to the newly allocated Code object.
if (!self_reference.is_null()) { if (!self_reference.is_null()) {
...@@ -3587,10 +3578,6 @@ static void MarkObjectRecursively(Object** p) { ...@@ -3587,10 +3578,6 @@ static void MarkObjectRecursively(Object** p) {
return; return;
} }
if (obj->IsCode()) {
Code::cast(obj)->ConvertICTargetsFromAddressToObject();
}
// not visited yet // not visited yet
Map* map_p = reinterpret_cast<Map*>(HeapObject::cast(map)); Map* map_p = reinterpret_cast<Map*>(HeapObject::cast(map));
...@@ -3646,10 +3633,6 @@ static void UnmarkObjectRecursively(Object** p) { ...@@ -3646,10 +3633,6 @@ static void UnmarkObjectRecursively(Object** p) {
obj->IterateBody(Map::cast(map_p)->instance_type(), obj->IterateBody(Map::cast(map_p)->instance_type(),
obj->SizeFromMap(Map::cast(map_p)), obj->SizeFromMap(Map::cast(map_p)),
&unmark_visitor); &unmark_visitor);
if (obj->IsCode()) {
Code::cast(obj)->ConvertICTargetsFromObjectToAddress();
}
} }
......
...@@ -265,18 +265,6 @@ class MarkingVisitor : public ObjectVisitor { ...@@ -265,18 +265,6 @@ class MarkingVisitor : public ObjectVisitor {
for (Object** p = start; p < end; p++) MarkObjectByPointer(p); for (Object** p = start; p < end; p++) MarkObjectByPointer(p);
} }
void BeginCodeIteration(Code* code) {
// When iterating over a code object during marking
// ic targets are derived pointers.
ASSERT(code->ic_flag() == Code::IC_TARGET_IS_ADDRESS);
}
void EndCodeIteration(Code* code) {
// If this is a compacting collection, set ic targets
// are pointing to object headers.
if (IsCompacting()) code->set_ic_flag(Code::IC_TARGET_IS_OBJECT);
}
void VisitCodeTarget(RelocInfo* rinfo) { void VisitCodeTarget(RelocInfo* rinfo) {
ASSERT(RelocInfo::IsCodeTarget(rinfo->rmode())); ASSERT(RelocInfo::IsCodeTarget(rinfo->rmode()));
Code* code = Code::GetCodeFromTargetAddress(rinfo->target_address()); Code* code = Code::GetCodeFromTargetAddress(rinfo->target_address());
...@@ -287,11 +275,6 @@ class MarkingVisitor : public ObjectVisitor { ...@@ -287,11 +275,6 @@ class MarkingVisitor : public ObjectVisitor {
} else { } else {
MarkCompactCollector::MarkObject(code); MarkCompactCollector::MarkObject(code);
} }
if (IsCompacting()) {
// When compacting we convert the target to a real object pointer.
code = Code::GetCodeFromTargetAddress(rinfo->target_address());
rinfo->set_target_object(code);
}
} }
void VisitDebugTarget(RelocInfo* rinfo) { void VisitDebugTarget(RelocInfo* rinfo) {
...@@ -1187,12 +1170,6 @@ static void SweepSpace(PagedSpace* space, DeallocateFunction dealloc) { ...@@ -1187,12 +1170,6 @@ static void SweepSpace(PagedSpace* space, DeallocateFunction dealloc) {
if (object->IsMarked()) { if (object->IsMarked()) {
object->ClearMark(); object->ClearMark();
MarkCompactCollector::tracer()->decrement_marked_count(); MarkCompactCollector::tracer()->decrement_marked_count();
if (MarkCompactCollector::IsCompacting() && object->IsCode()) {
// If this is compacting collection marked code objects have had
// their IC targets converted to objects.
// They need to be converted back to addresses.
Code::cast(object)->ConvertICTargetsFromObjectToAddress();
}
if (!is_previous_alive) { // Transition from free to live. if (!is_previous_alive) { // Transition from free to live.
dealloc(free_start, current - free_start); dealloc(free_start, current - free_start);
is_previous_alive = true; is_previous_alive = true;
...@@ -1398,6 +1375,14 @@ class UpdatingVisitor: public ObjectVisitor { ...@@ -1398,6 +1375,14 @@ class UpdatingVisitor: public ObjectVisitor {
for (Object** p = start; p < end; p++) UpdatePointer(p); for (Object** p = start; p < end; p++) UpdatePointer(p);
} }
void VisitCodeTarget(RelocInfo* rinfo) {
ASSERT(RelocInfo::IsCodeTarget(rinfo->rmode()));
Object* target = Code::GetCodeFromTargetAddress(rinfo->target_address());
VisitPointer(&target);
rinfo->set_target_address(
reinterpret_cast<Code*>(target)->instruction_start());
}
private: private:
void UpdatePointer(Object** p) { void UpdatePointer(Object** p) {
if (!(*p)->IsHeapObject()) return; if (!(*p)->IsHeapObject()) return;
...@@ -1631,11 +1616,6 @@ void MarkCompactCollector::RelocateObjects() { ...@@ -1631,11 +1616,6 @@ void MarkCompactCollector::RelocateObjects() {
ASSERT(live_cells == live_cell_objects_); ASSERT(live_cells == live_cell_objects_);
ASSERT(live_news == live_young_objects_); ASSERT(live_news == live_young_objects_);
// Notify code object in LO to convert IC target to address
// This must happen after lo_space_->Compact
LargeObjectIterator it(Heap::lo_space());
while (it.has_next()) { ConvertCodeICTargetToAddress(it.next()); }
// Flip from and to spaces // Flip from and to spaces
Heap::new_space()->Flip(); Heap::new_space()->Flip();
...@@ -1654,14 +1634,6 @@ void MarkCompactCollector::RelocateObjects() { ...@@ -1654,14 +1634,6 @@ void MarkCompactCollector::RelocateObjects() {
} }
int MarkCompactCollector::ConvertCodeICTargetToAddress(HeapObject* obj) {
if (obj->IsCode()) {
Code::cast(obj)->ConvertICTargetsFromObjectToAddress();
}
return obj->Size();
}
int MarkCompactCollector::RelocateMapObject(HeapObject* obj) { int MarkCompactCollector::RelocateMapObject(HeapObject* obj) {
// Recover map pointer. // Recover map pointer.
MapWord encoding = obj->map_word(); MapWord encoding = obj->map_word();
...@@ -1770,11 +1742,6 @@ int MarkCompactCollector::RelocateCodeObject(HeapObject* obj) { ...@@ -1770,11 +1742,6 @@ int MarkCompactCollector::RelocateCodeObject(HeapObject* obj) {
// Reset the map pointer. // Reset the map pointer.
int obj_size = RestoreMap(obj, Heap::code_space(), new_addr, map_addr); int obj_size = RestoreMap(obj, Heap::code_space(), new_addr, map_addr);
// Convert inline cache target to address using old address.
if (obj->IsCode()) {
Code::cast(obj)->ConvertICTargetsFromObjectToAddress();
}
Address old_addr = obj->address(); Address old_addr = obj->address();
if (new_addr != old_addr) { if (new_addr != old_addr) {
......
...@@ -733,7 +733,6 @@ void Code::CodePrint() { ...@@ -733,7 +733,6 @@ void Code::CodePrint() {
void Code::CodeVerify() { void Code::CodeVerify() {
CHECK(ic_flag() == IC_TARGET_IS_ADDRESS);
CHECK(IsAligned(reinterpret_cast<intptr_t>(instruction_start()), CHECK(IsAligned(reinterpret_cast<intptr_t>(instruction_start()),
static_cast<intptr_t>(kCodeAlignment))); static_cast<intptr_t>(kCodeAlignment)));
Address last_gc_pc = NULL; Address last_gc_pc = NULL;
......
...@@ -2538,16 +2538,6 @@ INT_ACCESSORS(Code, relocation_size, kRelocationSizeOffset) ...@@ -2538,16 +2538,6 @@ INT_ACCESSORS(Code, relocation_size, kRelocationSizeOffset)
INT_ACCESSORS(Code, sinfo_size, kSInfoSizeOffset) INT_ACCESSORS(Code, sinfo_size, kSInfoSizeOffset)
Code::ICTargetState Code::ic_flag() {
return static_cast<ICTargetState>(READ_BYTE_FIELD(this, kICFlagOffset));
}
void Code::set_ic_flag(ICTargetState value) {
WRITE_BYTE_FIELD(this, kICFlagOffset, value);
}
byte* Code::instruction_start() { byte* Code::instruction_start() {
return FIELD_ADDR(this, kHeaderSize); return FIELD_ADDR(this, kHeaderSize);
} }
......
...@@ -4955,60 +4955,25 @@ void SharedFunctionInfo::SharedFunctionInfoIterateBody(ObjectVisitor* v) { ...@@ -4955,60 +4955,25 @@ void SharedFunctionInfo::SharedFunctionInfoIterateBody(ObjectVisitor* v) {
} }
void ObjectVisitor::BeginCodeIteration(Code* code) {
ASSERT(code->ic_flag() == Code::IC_TARGET_IS_OBJECT);
}
void ObjectVisitor::VisitCodeTarget(RelocInfo* rinfo) { void ObjectVisitor::VisitCodeTarget(RelocInfo* rinfo) {
ASSERT(RelocInfo::IsCodeTarget(rinfo->rmode())); ASSERT(RelocInfo::IsCodeTarget(rinfo->rmode()));
VisitPointer(rinfo->target_object_address()); Object* target = Code::GetCodeFromTargetAddress(rinfo->target_address());
Object* old_target = target;
VisitPointer(&target);
CHECK_EQ(target, old_target); // VisitPointer doesn't change Code* *target.
} }
void ObjectVisitor::VisitDebugTarget(RelocInfo* rinfo) { void ObjectVisitor::VisitDebugTarget(RelocInfo* rinfo) {
ASSERT(RelocInfo::IsJSReturn(rinfo->rmode()) && rinfo->IsCallInstruction()); ASSERT(RelocInfo::IsJSReturn(rinfo->rmode()) && rinfo->IsCallInstruction());
VisitPointer(rinfo->call_object_address()); Object* target = Code::GetCodeFromTargetAddress(rinfo->call_address());
} Object* old_target = target;
VisitPointer(&target);
CHECK_EQ(target, old_target); // VisitPointer doesn't change Code* *target.
// Convert relocatable targets from address to code object address. This is
// mainly IC call targets but for debugging straight-line code can be replaced
// with a call instruction which also has to be relocated.
void Code::ConvertICTargetsFromAddressToObject() {
ASSERT(ic_flag() == IC_TARGET_IS_ADDRESS);
for (RelocIterator it(this, RelocInfo::kCodeTargetMask);
!it.done(); it.next()) {
Address ic_addr = it.rinfo()->target_address();
ASSERT(ic_addr != NULL);
HeapObject* code = Code::GetCodeFromTargetAddress(ic_addr);
ASSERT(code->IsHeapObject());
it.rinfo()->set_target_object(code);
}
#ifdef ENABLE_DEBUGGER_SUPPORT
if (Debug::has_break_points()) {
for (RelocIterator it(this, RelocInfo::ModeMask(RelocInfo::JS_RETURN));
!it.done();
it.next()) {
if (it.rinfo()->IsCallInstruction()) {
Address addr = it.rinfo()->call_address();
ASSERT(addr != NULL);
HeapObject* code = Code::GetCodeFromTargetAddress(addr);
ASSERT(code->IsHeapObject());
it.rinfo()->set_call_object(code);
}
}
}
#endif
set_ic_flag(IC_TARGET_IS_OBJECT);
} }
void Code::CodeIterateBody(ObjectVisitor* v) { void Code::CodeIterateBody(ObjectVisitor* v) {
v->BeginCodeIteration(this);
int mode_mask = RelocInfo::kCodeTargetMask | int mode_mask = RelocInfo::kCodeTargetMask |
RelocInfo::ModeMask(RelocInfo::EMBEDDED_OBJECT) | RelocInfo::ModeMask(RelocInfo::EMBEDDED_OBJECT) |
RelocInfo::ModeMask(RelocInfo::EXTERNAL_REFERENCE) | RelocInfo::ModeMask(RelocInfo::EXTERNAL_REFERENCE) |
...@@ -5035,38 +5000,6 @@ void Code::CodeIterateBody(ObjectVisitor* v) { ...@@ -5035,38 +5000,6 @@ void Code::CodeIterateBody(ObjectVisitor* v) {
} }
ScopeInfo<>::IterateScopeInfo(this, v); ScopeInfo<>::IterateScopeInfo(this, v);
v->EndCodeIteration(this);
}
void Code::ConvertICTargetsFromObjectToAddress() {
ASSERT(ic_flag() == IC_TARGET_IS_OBJECT);
for (RelocIterator it(this, RelocInfo::kCodeTargetMask);
!it.done(); it.next()) {
// We cannot use the safe cast (Code::cast) here, because we may be in
// the middle of relocating old objects during GC and the map pointer in
// the code object may be mangled
Code* code = reinterpret_cast<Code*>(it.rinfo()->target_object());
ASSERT((code != NULL) && code->IsHeapObject());
it.rinfo()->set_target_address(code->instruction_start());
}
#ifdef ENABLE_DEBUGGER_SUPPORT
if (Debug::has_break_points()) {
for (RelocIterator it(this, RelocInfo::ModeMask(RelocInfo::JS_RETURN));
!it.done();
it.next()) {
if (it.rinfo()->IsCallInstruction()) {
Code* code = reinterpret_cast<Code*>(it.rinfo()->call_object());
ASSERT((code != NULL) && code->IsHeapObject());
it.rinfo()->set_call_address(code->instruction_start());
}
}
}
#endif
set_ic_flag(IC_TARGET_IS_ADDRESS);
} }
......
...@@ -2520,13 +2520,6 @@ class Code: public HeapObject { ...@@ -2520,13 +2520,6 @@ class Code: public HeapObject {
NUMBER_OF_KINDS = KEYED_STORE_IC + 1 NUMBER_OF_KINDS = KEYED_STORE_IC + 1
}; };
// A state indicates that inline cache in this Code object contains
// objects or relative instruction addresses.
enum ICTargetState {
IC_TARGET_IS_ADDRESS,
IC_TARGET_IS_OBJECT
};
#ifdef ENABLE_DISASSEMBLER #ifdef ENABLE_DISASSEMBLER
// Printing // Printing
static const char* Kind2String(Kind kind); static const char* Kind2String(Kind kind);
...@@ -2566,12 +2559,6 @@ class Code: public HeapObject { ...@@ -2566,12 +2559,6 @@ class Code: public HeapObject {
inline bool is_keyed_store_stub() { return kind() == KEYED_STORE_IC; } inline bool is_keyed_store_stub() { return kind() == KEYED_STORE_IC; }
inline bool is_call_stub() { return kind() == CALL_IC; } inline bool is_call_stub() { return kind() == CALL_IC; }
// [ic_flag]: State of inline cache targets. The flag is set to the
// object variant in ConvertICTargetsFromAddressToObject, and set to
// the address variant in ConvertICTargetsFromObjectToAddress.
inline ICTargetState ic_flag();
inline void set_ic_flag(ICTargetState value);
// [major_key]: For kind STUB, the major key. // [major_key]: For kind STUB, the major key.
inline CodeStub::Major major_key(); inline CodeStub::Major major_key();
inline void set_major_key(CodeStub::Major major); inline void set_major_key(CodeStub::Major major);
...@@ -2617,12 +2604,6 @@ class Code: public HeapObject { ...@@ -2617,12 +2604,6 @@ class Code: public HeapObject {
// Returns the address of the scope information. // Returns the address of the scope information.
inline byte* sinfo_start(); inline byte* sinfo_start();
// Convert inline cache target from address to code object before GC.
void ConvertICTargetsFromAddressToObject();
// Convert inline cache target from code object to address after GC
void ConvertICTargetsFromObjectToAddress();
// Relocate the code by delta bytes. Called to signal that this code // Relocate the code by delta bytes. Called to signal that this code
// object has been moved by delta bytes. // object has been moved by delta bytes.
void Relocate(int delta); void Relocate(int delta);
...@@ -2678,7 +2659,6 @@ class Code: public HeapObject { ...@@ -2678,7 +2659,6 @@ class Code: public HeapObject {
~kCodeAlignmentMask; ~kCodeAlignmentMask;
// Byte offsets within kKindSpecificFlagsOffset. // Byte offsets within kKindSpecificFlagsOffset.
static const int kICFlagOffset = kKindSpecificFlagsOffset + 0;
static const int kStubMajorKeyOffset = kKindSpecificFlagsOffset + 1; static const int kStubMajorKeyOffset = kKindSpecificFlagsOffset + 1;
// Flags layout. // Flags layout.
...@@ -4810,9 +4790,6 @@ class ObjectVisitor BASE_EMBEDDED { ...@@ -4810,9 +4790,6 @@ class ObjectVisitor BASE_EMBEDDED {
// To allow lazy clearing of inline caches the visitor has // To allow lazy clearing of inline caches the visitor has
// a rich interface for iterating over Code objects.. // a rich interface for iterating over Code objects..
// Called prior to visiting the body of a Code object.
virtual void BeginCodeIteration(Code* code);
// Visits a code target in the instruction stream. // Visits a code target in the instruction stream.
virtual void VisitCodeTarget(RelocInfo* rinfo); virtual void VisitCodeTarget(RelocInfo* rinfo);
...@@ -4822,9 +4799,6 @@ class ObjectVisitor BASE_EMBEDDED { ...@@ -4822,9 +4799,6 @@ class ObjectVisitor BASE_EMBEDDED {
// Visits a debug call target in the instruction stream. // Visits a debug call target in the instruction stream.
virtual void VisitDebugTarget(RelocInfo* rinfo); virtual void VisitDebugTarget(RelocInfo* rinfo);
// Called after completing visiting the body of a Code object.
virtual void EndCodeIteration(Code* code) {}
// Handy shorthand for visiting a single pointer. // Handy shorthand for visiting a single pointer.
virtual void VisitPointer(Object** p) { VisitPointers(p, p + 1); } virtual void VisitPointer(Object** p) { VisitPointers(p, p + 1); }
......
...@@ -935,10 +935,6 @@ class ReferenceUpdater: public ObjectVisitor { ...@@ -935,10 +935,6 @@ class ReferenceUpdater: public ObjectVisitor {
} }
} }
// Do not assert that code targets have been converted to object pointers.
virtual void BeginCodeIteration(Code* code) {
}
virtual void VisitCodeTarget(RelocInfo* rinfo) { virtual void VisitCodeTarget(RelocInfo* rinfo) {
ASSERT(RelocInfo::IsCodeTarget(rinfo->rmode())); ASSERT(RelocInfo::IsCodeTarget(rinfo->rmode()));
Code* target = Code::GetCodeFromTargetAddress(rinfo->target_address()); Code* target = Code::GetCodeFromTargetAddress(rinfo->target_address());
......
...@@ -154,7 +154,6 @@ class Serializer: public ObjectVisitor { ...@@ -154,7 +154,6 @@ class Serializer: public ObjectVisitor {
private: private:
friend class ReferenceUpdater; friend class ReferenceUpdater;
virtual void BeginCodeIteration(Code* code) { }
virtual void VisitPointers(Object** start, Object** end); virtual void VisitPointers(Object** start, Object** end);
virtual void VisitCodeTarget(RelocInfo* rinfo); virtual void VisitCodeTarget(RelocInfo* rinfo);
bool IsVisited(HeapObject* obj); bool IsVisited(HeapObject* obj);
...@@ -290,7 +289,6 @@ class Deserializer: public ObjectVisitor { ...@@ -290,7 +289,6 @@ class Deserializer: public ObjectVisitor {
private: private:
virtual void VisitPointers(Object** start, Object** end); virtual void VisitPointers(Object** start, Object** end);
virtual void BeginCodeIteration(Code* code) { }
virtual void VisitCodeTarget(RelocInfo* rinfo); virtual void VisitCodeTarget(RelocInfo* rinfo);
virtual void VisitExternalReferences(Address* start, Address* end); virtual void VisitExternalReferences(Address* start, Address* end);
virtual void VisitRuntimeEntry(RelocInfo* rinfo); virtual void VisitRuntimeEntry(RelocInfo* rinfo);
......
...@@ -827,13 +827,7 @@ void PagedSpace::Verify(ObjectVisitor* visitor) { ...@@ -827,13 +827,7 @@ void PagedSpace::Verify(ObjectVisitor* visitor) {
// have their remembered set bits set if required as determined // have their remembered set bits set if required as determined
// by the visitor. // by the visitor.
int size = object->Size(); int size = object->Size();
if (object->IsCode()) { object->IterateBody(map->instance_type(), size, visitor);
Code::cast(object)->ConvertICTargetsFromAddressToObject();
object->IterateBody(map->instance_type(), size, visitor);
Code::cast(object)->ConvertICTargetsFromObjectToAddress();
} else {
object->IterateBody(map->instance_type(), size, visitor);
}
current += size; current += size;
} }
...@@ -2574,11 +2568,9 @@ void LargeObjectSpace::Verify() { ...@@ -2574,11 +2568,9 @@ void LargeObjectSpace::Verify() {
// Byte arrays and strings don't have interior pointers. // Byte arrays and strings don't have interior pointers.
if (object->IsCode()) { if (object->IsCode()) {
VerifyPointersVisitor code_visitor; VerifyPointersVisitor code_visitor;
Code::cast(object)->ConvertICTargetsFromAddressToObject();
object->IterateBody(map->instance_type(), object->IterateBody(map->instance_type(),
object->Size(), object->Size(),
&code_visitor); &code_visitor);
Code::cast(object)->ConvertICTargetsFromObjectToAddress();
} else if (object->IsFixedArray()) { } else if (object->IsFixedArray()) {
// We loop over fixed arrays ourselves, rather then using the visitor, // We loop over fixed arrays ourselves, rather then using the visitor,
// because the visitor doesn't support the start/offset iteration // because the visitor doesn't support the start/offset iteration
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment