Commit 687537de authored by rmcilroy@chromium.org's avatar rmcilroy@chromium.org

Fix some out-of-line constant pool garbage collection bugs.

This CL fixes some bugs in the out of line constant pool implementation when
constant pools are GCed.  Namely:
  - Push/Pop pp register in exit frames and VisitPointer on it to ensure it is
    updated if the ConstantPoolArray is moved by GC.
  - Mark pp as a SafePoint Register for optimized functions.
  - Ensure that StandardFrame::IterateExpressions also iterates over the
    constant pool pointer in the stackframe.
  - Fix calculation of last_ptr_offset in ConstantPoolArray body iterator.
  - Make ensure that CONSTANT_POOL_ARRAY_TYPE is a pointer object InstanceType.

R=ulan@chromium.org

Review URL: https://codereview.chromium.org/123263005

git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@18473 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
parent 0030356c
...@@ -56,6 +56,13 @@ Register StubFailureTrampolineFrame::constant_pool_pointer_register() { ...@@ -56,6 +56,13 @@ Register StubFailureTrampolineFrame::constant_pool_pointer_register() {
} }
Object*& ExitFrame::constant_pool_slot() const {
ASSERT(FLAG_enable_ool_constant_pool);
const int offset = ExitFrameConstants::kConstantPoolOffset;
return Memory::Object_at(fp() + offset);
}
} } // namespace v8::internal } } // namespace v8::internal
#endif // V8_TARGET_ARCH_ARM #endif // V8_TARGET_ARCH_ARM
...@@ -109,8 +109,13 @@ class EntryFrameConstants : public AllStatic { ...@@ -109,8 +109,13 @@ class EntryFrameConstants : public AllStatic {
class ExitFrameConstants : public AllStatic { class ExitFrameConstants : public AllStatic {
public: public:
static const int kCodeOffset = -2 * kPointerSize; static const int kFrameSize = FLAG_enable_ool_constant_pool ?
static const int kSPOffset = -1 * kPointerSize; 3 * kPointerSize : 2 * kPointerSize;
static const int kConstantPoolOffset = FLAG_enable_ool_constant_pool ?
-3 * kPointerSize : 0;
static const int kCodeOffset = -2 * kPointerSize;
static const int kSPOffset = -1 * kPointerSize;
// The caller fields are below the frame pointer on the stack. // The caller fields are below the frame pointer on the stack.
static const int kCallerFPOffset = 0 * kPointerSize; static const int kCallerFPOffset = 0 * kPointerSize;
......
...@@ -979,6 +979,10 @@ void LCodeGen::RecordSafepoint( ...@@ -979,6 +979,10 @@ void LCodeGen::RecordSafepoint(
safepoint.DefinePointerRegister(ToRegister(pointer), zone()); safepoint.DefinePointerRegister(ToRegister(pointer), zone());
} }
} }
if (FLAG_enable_ool_constant_pool && (kind & Safepoint::kWithRegisters)) {
// Register pp always contains a pointer to the constant pool.
safepoint.DefinePointerRegister(pp, zone());
}
} }
......
...@@ -967,11 +967,14 @@ void MacroAssembler::EnterExitFrame(bool save_doubles, int stack_space) { ...@@ -967,11 +967,14 @@ void MacroAssembler::EnterExitFrame(bool save_doubles, int stack_space) {
Push(lr, fp); Push(lr, fp);
mov(fp, Operand(sp)); // Set up new frame pointer. mov(fp, Operand(sp)); // Set up new frame pointer.
// Reserve room for saved entry sp and code object. // Reserve room for saved entry sp and code object.
sub(sp, sp, Operand(2 * kPointerSize)); sub(sp, sp, Operand(ExitFrameConstants::kFrameSize));
if (emit_debug_code()) { if (emit_debug_code()) {
mov(ip, Operand::Zero()); mov(ip, Operand::Zero());
str(ip, MemOperand(fp, ExitFrameConstants::kSPOffset)); str(ip, MemOperand(fp, ExitFrameConstants::kSPOffset));
} }
if (FLAG_enable_ool_constant_pool) {
str(pp, MemOperand(fp, ExitFrameConstants::kConstantPoolOffset));
}
mov(ip, Operand(CodeObject())); mov(ip, Operand(CodeObject()));
str(ip, MemOperand(fp, ExitFrameConstants::kCodeOffset)); str(ip, MemOperand(fp, ExitFrameConstants::kCodeOffset));
...@@ -985,8 +988,10 @@ void MacroAssembler::EnterExitFrame(bool save_doubles, int stack_space) { ...@@ -985,8 +988,10 @@ void MacroAssembler::EnterExitFrame(bool save_doubles, int stack_space) {
if (save_doubles) { if (save_doubles) {
SaveFPRegs(sp, ip); SaveFPRegs(sp, ip);
// Note that d0 will be accessible at // Note that d0 will be accessible at
// fp - 2 * kPointerSize - DwVfpRegister::kMaxNumRegisters * kDoubleSize, // fp - ExitFrameConstants::kFrameSize -
// since the sp slot and code slot were pushed after the fp. // DwVfpRegister::kMaxNumRegisters * kDoubleSize,
// since the sp slot, code slot and constant pool slot (if
// FLAG_enable_ool_constant_pool) were pushed after the fp.
} }
// Reserve place for the return address and stack space and align the frame // Reserve place for the return address and stack space and align the frame
...@@ -1042,7 +1047,7 @@ void MacroAssembler::LeaveExitFrame(bool save_doubles, ...@@ -1042,7 +1047,7 @@ void MacroAssembler::LeaveExitFrame(bool save_doubles,
// Optionally restore all double registers. // Optionally restore all double registers.
if (save_doubles) { if (save_doubles) {
// Calculate the stack location of the saved doubles and restore them. // Calculate the stack location of the saved doubles and restore them.
const int offset = 2 * kPointerSize; const int offset = ExitFrameConstants::kFrameSize;
sub(r3, fp, sub(r3, fp,
Operand(offset + DwVfpRegister::kMaxNumRegisters * kDoubleSize)); Operand(offset + DwVfpRegister::kMaxNumRegisters * kDoubleSize));
RestoreFPRegs(r3, ip); RestoreFPRegs(r3, ip);
...@@ -1065,6 +1070,9 @@ void MacroAssembler::LeaveExitFrame(bool save_doubles, ...@@ -1065,6 +1070,9 @@ void MacroAssembler::LeaveExitFrame(bool save_doubles,
#endif #endif
// Tear down the exit frame, pop the arguments, and return. // Tear down the exit frame, pop the arguments, and return.
if (FLAG_enable_ool_constant_pool) {
ldr(pp, MemOperand(fp, ExitFrameConstants::kConstantPoolOffset));
}
mov(sp, Operand(fp)); mov(sp, Operand(fp));
ldm(ia_w, sp, fp.bit() | lr.bit()); ldm(ia_w, sp, fp.bit() | lr.bit());
if (argument_count.is_valid()) { if (argument_count.is_valid()) {
......
...@@ -544,6 +544,9 @@ void ExitFrame::Iterate(ObjectVisitor* v) const { ...@@ -544,6 +544,9 @@ void ExitFrame::Iterate(ObjectVisitor* v) const {
// the calling frame. // the calling frame.
IteratePc(v, pc_address(), LookupCode()); IteratePc(v, pc_address(), LookupCode());
v->VisitPointer(&code_slot()); v->VisitPointer(&code_slot());
if (FLAG_enable_ool_constant_pool) {
v->VisitPointer(&constant_pool_slot());
}
} }
...@@ -1343,7 +1346,7 @@ void EntryFrame::Iterate(ObjectVisitor* v) const { ...@@ -1343,7 +1346,7 @@ void EntryFrame::Iterate(ObjectVisitor* v) const {
void StandardFrame::IterateExpressions(ObjectVisitor* v) const { void StandardFrame::IterateExpressions(ObjectVisitor* v) const {
const int offset = StandardFrameConstants::kContextOffset; const int offset = StandardFrameConstants::kLastObjectOffset;
Object** base = &Memory::Object_at(sp()); Object** base = &Memory::Object_at(sp());
Object** limit = &Memory::Object_at(fp() + offset) + 1; Object** limit = &Memory::Object_at(fp() + offset) + 1;
for (StackHandlerIterator it(this, top_handler()); !it.done(); it.Advance()) { for (StackHandlerIterator it(this, top_handler()); !it.done(); it.Advance()) {
...@@ -1381,7 +1384,7 @@ void StubFailureTrampolineFrame::Iterate(ObjectVisitor* v) const { ...@@ -1381,7 +1384,7 @@ void StubFailureTrampolineFrame::Iterate(ObjectVisitor* v) const {
kFirstRegisterParameterFrameOffset); kFirstRegisterParameterFrameOffset);
v->VisitPointers(base, limit); v->VisitPointers(base, limit);
base = &Memory::Object_at(fp() + StandardFrameConstants::kMarkerOffset); base = &Memory::Object_at(fp() + StandardFrameConstants::kMarkerOffset);
const int offset = StandardFrameConstants::kContextOffset; const int offset = StandardFrameConstants::kLastObjectOffset;
limit = &Memory::Object_at(fp() + offset) + 1; limit = &Memory::Object_at(fp() + offset) + 1;
v->VisitPointers(base, limit); v->VisitPointers(base, limit);
IteratePc(v, pc_address(), LookupCode()); IteratePc(v, pc_address(), LookupCode());
......
...@@ -143,6 +143,7 @@ class StackHandler BASE_EMBEDDED { ...@@ -143,6 +143,7 @@ class StackHandler BASE_EMBEDDED {
inline Kind kind() const; inline Kind kind() const;
inline unsigned index() const; inline unsigned index() const;
inline Object** constant_pool_address() const;
inline Object** context_address() const; inline Object** context_address() const;
inline Object** code_address() const; inline Object** code_address() const;
inline void SetFp(Address slot, Address fp); inline void SetFp(Address slot, Address fp);
...@@ -168,8 +169,8 @@ class StandardFrameConstants : public AllStatic { ...@@ -168,8 +169,8 @@ class StandardFrameConstants : public AllStatic {
public: public:
// Fixed part of the frame consists of return address, caller fp, // Fixed part of the frame consists of return address, caller fp,
// constant pool (if FLAG_enable_ool_constant_pool), context, and function. // constant pool (if FLAG_enable_ool_constant_pool), context, and function.
// StandardFrame::IterateExpressions assumes that kContextOffset is the last // StandardFrame::IterateExpressions assumes that kLastObjectOffset is the
// object pointer. // last object pointer.
static const int kCPSlotSize = static const int kCPSlotSize =
FLAG_enable_ool_constant_pool ? kPointerSize : 0; FLAG_enable_ool_constant_pool ? kPointerSize : 0;
static const int kFixedFrameSizeFromFp = 2 * kPointerSize + kCPSlotSize; static const int kFixedFrameSizeFromFp = 2 * kPointerSize + kCPSlotSize;
...@@ -183,6 +184,9 @@ class StandardFrameConstants : public AllStatic { ...@@ -183,6 +184,9 @@ class StandardFrameConstants : public AllStatic {
static const int kCallerFPOffset = 0 * kPointerSize; static const int kCallerFPOffset = 0 * kPointerSize;
static const int kCallerPCOffset = +1 * kFPOnStackSize; static const int kCallerPCOffset = +1 * kFPOnStackSize;
static const int kCallerSPOffset = kCallerPCOffset + 1 * kPCOnStackSize; static const int kCallerSPOffset = kCallerPCOffset + 1 * kPCOnStackSize;
static const int kLastObjectOffset = FLAG_enable_ool_constant_pool ?
kConstantPoolOffset : kContextOffset;
}; };
...@@ -423,6 +427,7 @@ class ExitFrame: public StackFrame { ...@@ -423,6 +427,7 @@ class ExitFrame: public StackFrame {
virtual Code* unchecked_code() const; virtual Code* unchecked_code() const;
Object*& code_slot() const; Object*& code_slot() const;
Object*& constant_pool_slot() const;
// Garbage collection support. // Garbage collection support.
virtual void Iterate(ObjectVisitor* v) const; virtual void Iterate(ObjectVisitor* v) const;
......
...@@ -54,6 +54,12 @@ Register StubFailureTrampolineFrame::constant_pool_pointer_register() { ...@@ -54,6 +54,12 @@ Register StubFailureTrampolineFrame::constant_pool_pointer_register() {
} }
Object*& ExitFrame::constant_pool_slot() const {
UNREACHABLE();
return Memory::Object_at(NULL);
}
} } // namespace v8::internal } } // namespace v8::internal
#endif // V8_TARGET_ARCH_IA32 #endif // V8_TARGET_ARCH_IA32
...@@ -73,6 +73,8 @@ class EntryFrameConstants : public AllStatic { ...@@ -73,6 +73,8 @@ class EntryFrameConstants : public AllStatic {
class ExitFrameConstants : public AllStatic { class ExitFrameConstants : public AllStatic {
public: public:
static const int kFrameSize = 2 * kPointerSize;
static const int kCodeOffset = -2 * kPointerSize; static const int kCodeOffset = -2 * kPointerSize;
static const int kSPOffset = -1 * kPointerSize; static const int kSPOffset = -1 * kPointerSize;
......
...@@ -54,6 +54,12 @@ Register StubFailureTrampolineFrame::constant_pool_pointer_register() { ...@@ -54,6 +54,12 @@ Register StubFailureTrampolineFrame::constant_pool_pointer_register() {
} }
Object*& ExitFrame::constant_pool_slot() const {
UNREACHABLE();
return Memory::Object_at(NULL);
}
} } // namespace v8::internal } } // namespace v8::internal
#endif // V8_TARGET_ARCH_MIPS #endif // V8_TARGET_ARCH_MIPS
...@@ -161,12 +161,9 @@ class EntryFrameConstants : public AllStatic { ...@@ -161,12 +161,9 @@ class EntryFrameConstants : public AllStatic {
class ExitFrameConstants : public AllStatic { class ExitFrameConstants : public AllStatic {
public: public:
// See some explanation in MacroAssembler::EnterExitFrame. static const int kFrameSize = 2 * kPointerSize;
// This marks the top of the extra allocated stack space.
static const int kStackSpaceOffset = -3 * kPointerSize;
static const int kCodeOffset = -2 * kPointerSize; static const int kCodeOffset = -2 * kPointerSize;
static const int kSPOffset = -1 * kPointerSize; static const int kSPOffset = -1 * kPointerSize;
// The caller fields are below the frame pointer on the stack. // The caller fields are below the frame pointer on the stack.
......
...@@ -482,7 +482,7 @@ void StaticMarkingVisitor<StaticVisitor>::VisitConstantPoolArray( ...@@ -482,7 +482,7 @@ void StaticMarkingVisitor<StaticVisitor>::VisitConstantPoolArray(
constant_pool->first_ptr_index()); constant_pool->first_ptr_index());
int last_ptr_offset = constant_pool->OffsetOfElementAt( int last_ptr_offset = constant_pool->OffsetOfElementAt(
constant_pool->first_ptr_index() + constant_pool->first_ptr_index() +
constant_pool->count_of_ptr_entries()); constant_pool->count_of_ptr_entries() - 1);
StaticVisitor::VisitPointers( StaticVisitor::VisitPointers(
heap, heap,
HeapObject::RawField(object, first_ptr_offset), HeapObject::RawField(object, first_ptr_offset),
......
...@@ -9460,7 +9460,7 @@ void ConstantPoolArray::ConstantPoolIterateBody(ObjectVisitor* v) { ...@@ -9460,7 +9460,7 @@ void ConstantPoolArray::ConstantPoolIterateBody(ObjectVisitor* v) {
if (count_of_ptr_entries() > 0) { if (count_of_ptr_entries() > 0) {
int first_ptr_offset = OffsetOfElementAt(first_ptr_index()); int first_ptr_offset = OffsetOfElementAt(first_ptr_index());
int last_ptr_offset = int last_ptr_offset =
OffsetOfElementAt(first_ptr_index() + count_of_ptr_entries()); OffsetOfElementAt(first_ptr_index() + count_of_ptr_entries() - 1);
v->VisitPointers( v->VisitPointers(
HeapObject::RawField(this, first_ptr_offset), HeapObject::RawField(this, first_ptr_offset),
HeapObject::RawField(this, last_ptr_offset)); HeapObject::RawField(this, last_ptr_offset));
......
...@@ -721,7 +721,6 @@ enum InstanceType { ...@@ -721,7 +721,6 @@ enum InstanceType {
EXTERNAL_DOUBLE_ARRAY_TYPE, EXTERNAL_DOUBLE_ARRAY_TYPE,
EXTERNAL_PIXEL_ARRAY_TYPE, // LAST_EXTERNAL_ARRAY_TYPE EXTERNAL_PIXEL_ARRAY_TYPE, // LAST_EXTERNAL_ARRAY_TYPE
FIXED_DOUBLE_ARRAY_TYPE, FIXED_DOUBLE_ARRAY_TYPE,
CONSTANT_POOL_ARRAY_TYPE,
FILLER_TYPE, // LAST_DATA_TYPE FILLER_TYPE, // LAST_DATA_TYPE
// Structs. // Structs.
...@@ -752,6 +751,7 @@ enum InstanceType { ...@@ -752,6 +751,7 @@ enum InstanceType {
BREAK_POINT_INFO_TYPE, BREAK_POINT_INFO_TYPE,
FIXED_ARRAY_TYPE, FIXED_ARRAY_TYPE,
CONSTANT_POOL_ARRAY_TYPE,
SHARED_FUNCTION_INFO_TYPE, SHARED_FUNCTION_INFO_TYPE,
JS_MESSAGE_OBJECT_TYPE, JS_MESSAGE_OBJECT_TYPE,
......
...@@ -54,6 +54,12 @@ Register StubFailureTrampolineFrame::constant_pool_pointer_register() { ...@@ -54,6 +54,12 @@ Register StubFailureTrampolineFrame::constant_pool_pointer_register() {
} }
Object*& ExitFrame::constant_pool_slot() const {
UNREACHABLE();
return Memory::Object_at(NULL);
}
} } // namespace v8::internal } } // namespace v8::internal
#endif // V8_TARGET_ARCH_X64 #endif // V8_TARGET_ARCH_X64
...@@ -66,6 +66,8 @@ class EntryFrameConstants : public AllStatic { ...@@ -66,6 +66,8 @@ class EntryFrameConstants : public AllStatic {
class ExitFrameConstants : public AllStatic { class ExitFrameConstants : public AllStatic {
public: public:
static const int kFrameSize = 2 * kPointerSize;
static const int kCodeOffset = -2 * kPointerSize; static const int kCodeOffset = -2 * kPointerSize;
static const int kSPOffset = -1 * kPointerSize; static const int kSPOffset = -1 * kPointerSize;
......
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