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() {
HeapObjectIterator code_it(Heap::code_space());
while (code_it.has_next()) {
HeapObject* object = code_it.next();
if (object->IsCode()) {
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);
}
object->Iterate(&v);
}
HeapObjectIterator data_it(Heap::old_data_space());
......@@ -1935,7 +1927,6 @@ Object* Heap::CreateCode(const CodeDesc& desc,
code->set_relocation_size(desc.reloc_size);
code->set_sinfo_size(sinfo_size);
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
// point to the newly allocated Code object.
if (!self_reference.is_null()) {
......@@ -3587,10 +3578,6 @@ static void MarkObjectRecursively(Object** p) {
return;
}
if (obj->IsCode()) {
Code::cast(obj)->ConvertICTargetsFromAddressToObject();
}
// not visited yet
Map* map_p = reinterpret_cast<Map*>(HeapObject::cast(map));
......@@ -3646,10 +3633,6 @@ static void UnmarkObjectRecursively(Object** p) {
obj->IterateBody(Map::cast(map_p)->instance_type(),
obj->SizeFromMap(Map::cast(map_p)),
&unmark_visitor);
if (obj->IsCode()) {
Code::cast(obj)->ConvertICTargetsFromObjectToAddress();
}
}
......
......@@ -265,18 +265,6 @@ class MarkingVisitor : public ObjectVisitor {
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) {
ASSERT(RelocInfo::IsCodeTarget(rinfo->rmode()));
Code* code = Code::GetCodeFromTargetAddress(rinfo->target_address());
......@@ -287,11 +275,6 @@ class MarkingVisitor : public ObjectVisitor {
} else {
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) {
......@@ -1187,12 +1170,6 @@ static void SweepSpace(PagedSpace* space, DeallocateFunction dealloc) {
if (object->IsMarked()) {
object->ClearMark();
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.
dealloc(free_start, current - free_start);
is_previous_alive = true;
......@@ -1398,6 +1375,14 @@ class UpdatingVisitor: public ObjectVisitor {
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:
void UpdatePointer(Object** p) {
if (!(*p)->IsHeapObject()) return;
......@@ -1631,11 +1616,6 @@ void MarkCompactCollector::RelocateObjects() {
ASSERT(live_cells == live_cell_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
Heap::new_space()->Flip();
......@@ -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) {
// Recover map pointer.
MapWord encoding = obj->map_word();
......@@ -1770,11 +1742,6 @@ int MarkCompactCollector::RelocateCodeObject(HeapObject* obj) {
// Reset the map pointer.
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();
if (new_addr != old_addr) {
......
......@@ -733,7 +733,6 @@ void Code::CodePrint() {
void Code::CodeVerify() {
CHECK(ic_flag() == IC_TARGET_IS_ADDRESS);
CHECK(IsAligned(reinterpret_cast<intptr_t>(instruction_start()),
static_cast<intptr_t>(kCodeAlignment)));
Address last_gc_pc = NULL;
......
......@@ -2538,16 +2538,6 @@ INT_ACCESSORS(Code, relocation_size, kRelocationSizeOffset)
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() {
return FIELD_ADDR(this, kHeaderSize);
}
......
......@@ -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) {
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) {
ASSERT(RelocInfo::IsJSReturn(rinfo->rmode()) && rinfo->IsCallInstruction());
VisitPointer(rinfo->call_object_address());
}
// 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);
Object* target = Code::GetCodeFromTargetAddress(rinfo->call_address());
Object* old_target = target;
VisitPointer(&target);
CHECK_EQ(target, old_target); // VisitPointer doesn't change Code* *target.
}
void Code::CodeIterateBody(ObjectVisitor* v) {
v->BeginCodeIteration(this);
int mode_mask = RelocInfo::kCodeTargetMask |
RelocInfo::ModeMask(RelocInfo::EMBEDDED_OBJECT) |
RelocInfo::ModeMask(RelocInfo::EXTERNAL_REFERENCE) |
......@@ -5035,38 +5000,6 @@ void Code::CodeIterateBody(ObjectVisitor* 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 {
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
// Printing
static const char* Kind2String(Kind kind);
......@@ -2566,12 +2559,6 @@ class Code: public HeapObject {
inline bool is_keyed_store_stub() { return kind() == KEYED_STORE_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.
inline CodeStub::Major major_key();
inline void set_major_key(CodeStub::Major major);
......@@ -2617,12 +2604,6 @@ class Code: public HeapObject {
// Returns the address of the scope information.
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
// object has been moved by delta bytes.
void Relocate(int delta);
......@@ -2678,7 +2659,6 @@ class Code: public HeapObject {
~kCodeAlignmentMask;
// Byte offsets within kKindSpecificFlagsOffset.
static const int kICFlagOffset = kKindSpecificFlagsOffset + 0;
static const int kStubMajorKeyOffset = kKindSpecificFlagsOffset + 1;
// Flags layout.
......@@ -4810,9 +4790,6 @@ class ObjectVisitor BASE_EMBEDDED {
// To allow lazy clearing of inline caches the visitor has
// 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.
virtual void VisitCodeTarget(RelocInfo* rinfo);
......@@ -4822,9 +4799,6 @@ class ObjectVisitor BASE_EMBEDDED {
// Visits a debug call target in the instruction stream.
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.
virtual void VisitPointer(Object** p) { VisitPointers(p, p + 1); }
......
......@@ -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) {
ASSERT(RelocInfo::IsCodeTarget(rinfo->rmode()));
Code* target = Code::GetCodeFromTargetAddress(rinfo->target_address());
......
......@@ -154,7 +154,6 @@ class Serializer: public ObjectVisitor {
private:
friend class ReferenceUpdater;
virtual void BeginCodeIteration(Code* code) { }
virtual void VisitPointers(Object** start, Object** end);
virtual void VisitCodeTarget(RelocInfo* rinfo);
bool IsVisited(HeapObject* obj);
......@@ -290,7 +289,6 @@ class Deserializer: public ObjectVisitor {
private:
virtual void VisitPointers(Object** start, Object** end);
virtual void BeginCodeIteration(Code* code) { }
virtual void VisitCodeTarget(RelocInfo* rinfo);
virtual void VisitExternalReferences(Address* start, Address* end);
virtual void VisitRuntimeEntry(RelocInfo* rinfo);
......
......@@ -827,13 +827,7 @@ void PagedSpace::Verify(ObjectVisitor* visitor) {
// have their remembered set bits set if required as determined
// by the visitor.
int size = object->Size();
if (object->IsCode()) {
Code::cast(object)->ConvertICTargetsFromAddressToObject();
object->IterateBody(map->instance_type(), size, visitor);
Code::cast(object)->ConvertICTargetsFromObjectToAddress();
} else {
object->IterateBody(map->instance_type(), size, visitor);
}
object->IterateBody(map->instance_type(), size, visitor);
current += size;
}
......@@ -2574,11 +2568,9 @@ void LargeObjectSpace::Verify() {
// Byte arrays and strings don't have interior pointers.
if (object->IsCode()) {
VerifyPointersVisitor code_visitor;
Code::cast(object)->ConvertICTargetsFromAddressToObject();
object->IterateBody(map->instance_type(),
object->Size(),
&code_visitor);
Code::cast(object)->ConvertICTargetsFromObjectToAddress();
} else if (object->IsFixedArray()) {
// We loop over fixed arrays ourselves, rather then using the visitor,
// 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