Commit 7f622cff authored by rmcilroy@chromium.org's avatar rmcilroy@chromium.org

Introduce FrameAndConstantPoolScope and ConstantPoolUnavailableScope.

Adds FrameAndConstantPoolScope and ConstantPoolUnavailableScope to enable
scoped management of constant pool availability.  Also load constant pool
pointer when entering an internal frame scope.

R=rodolph.perfetta@arm.com, ulan@chromium.org

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

git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@19858 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
parent 6b864014
...@@ -530,6 +530,8 @@ Assembler::Assembler(Isolate* isolate, void* buffer, int buffer_size) ...@@ -530,6 +530,8 @@ Assembler::Assembler(Isolate* isolate, void* buffer, int buffer_size)
first_const_pool_32_use_ = -1; first_const_pool_32_use_ = -1;
first_const_pool_64_use_ = -1; first_const_pool_64_use_ = -1;
last_bound_pos_ = 0; last_bound_pos_ = 0;
constant_pool_available_ = !FLAG_enable_ool_constant_pool;
constant_pool_full_ = false;
ClearRecordedAstId(); ClearRecordedAstId();
} }
......
...@@ -1458,6 +1458,14 @@ class Assembler : public AssemblerBase { ...@@ -1458,6 +1458,14 @@ class Assembler : public AssemblerBase {
// Check if is time to emit a constant pool. // Check if is time to emit a constant pool.
void CheckConstPool(bool force_emit, bool require_jump); void CheckConstPool(bool force_emit, bool require_jump);
bool can_use_constant_pool() const {
return is_constant_pool_available() && !constant_pool_full_;
}
void set_constant_pool_full() {
constant_pool_full_ = true;
}
protected: protected:
// Relocation for a type-recording IC has the AST id added to it. This // Relocation for a type-recording IC has the AST id added to it. This
// member variable is a way to pass the information from the call site to // member variable is a way to pass the information from the call site to
...@@ -1511,6 +1519,14 @@ class Assembler : public AssemblerBase { ...@@ -1511,6 +1519,14 @@ class Assembler : public AssemblerBase {
(pc_offset() < no_const_pool_before_); (pc_offset() < no_const_pool_before_);
} }
bool is_constant_pool_available() const {
return constant_pool_available_;
}
void set_constant_pool_available(bool available) {
constant_pool_available_ = available;
}
private: private:
int next_buffer_check_; // pc offset of next buffer check int next_buffer_check_; // pc offset of next buffer check
...@@ -1571,6 +1587,13 @@ class Assembler : public AssemblerBase { ...@@ -1571,6 +1587,13 @@ class Assembler : public AssemblerBase {
// The bound position, before this we cannot do instruction elimination. // The bound position, before this we cannot do instruction elimination.
int last_bound_pos_; int last_bound_pos_;
// Indicates whether the constant pool can be accessed, which is only possible
// if the pp register points to the current code object's constant pool.
bool constant_pool_available_;
// Indicates whether the constant pool is too full to accept new entries due
// to the ldr instruction's limitted immediate offset range.
bool constant_pool_full_;
// Code emission // Code emission
inline void CheckBuffer(); inline void CheckBuffer();
void GrowBuffer(); void GrowBuffer();
...@@ -1607,6 +1630,8 @@ class Assembler : public AssemblerBase { ...@@ -1607,6 +1630,8 @@ class Assembler : public AssemblerBase {
friend class RelocInfo; friend class RelocInfo;
friend class CodePatcher; friend class CodePatcher;
friend class BlockConstPoolScope; friend class BlockConstPoolScope;
friend class FrameAndConstantPoolScope;
friend class ConstantPoolUnavailableScope;
PositionsRecorder positions_recorder_; PositionsRecorder positions_recorder_;
friend class PositionsRecorder; friend class PositionsRecorder;
......
...@@ -261,7 +261,7 @@ void Builtins::Generate_StringConstructCode(MacroAssembler* masm) { ...@@ -261,7 +261,7 @@ void Builtins::Generate_StringConstructCode(MacroAssembler* masm) {
__ push(function); // Preserve the function. __ push(function); // Preserve the function.
__ IncrementCounter(counters->string_ctor_conversions(), 1, r3, r4); __ IncrementCounter(counters->string_ctor_conversions(), 1, r3, r4);
{ {
FrameScope scope(masm, StackFrame::INTERNAL); FrameAndConstantPoolScope scope(masm, StackFrame::INTERNAL);
__ push(r0); __ push(r0);
__ InvokeBuiltin(Builtins::TO_STRING, CALL_FUNCTION); __ InvokeBuiltin(Builtins::TO_STRING, CALL_FUNCTION);
} }
...@@ -281,7 +281,7 @@ void Builtins::Generate_StringConstructCode(MacroAssembler* masm) { ...@@ -281,7 +281,7 @@ void Builtins::Generate_StringConstructCode(MacroAssembler* masm) {
__ bind(&gc_required); __ bind(&gc_required);
__ IncrementCounter(counters->string_ctor_gc_required(), 1, r3, r4); __ IncrementCounter(counters->string_ctor_gc_required(), 1, r3, r4);
{ {
FrameScope scope(masm, StackFrame::INTERNAL); FrameAndConstantPoolScope scope(masm, StackFrame::INTERNAL);
__ push(argument); __ push(argument);
__ CallRuntime(Runtime::kNewStringWrapper, 1); __ CallRuntime(Runtime::kNewStringWrapper, 1);
} }
...@@ -291,7 +291,7 @@ void Builtins::Generate_StringConstructCode(MacroAssembler* masm) { ...@@ -291,7 +291,7 @@ void Builtins::Generate_StringConstructCode(MacroAssembler* masm) {
static void CallRuntimePassFunction( static void CallRuntimePassFunction(
MacroAssembler* masm, Runtime::FunctionId function_id) { MacroAssembler* masm, Runtime::FunctionId function_id) {
FrameScope scope(masm, StackFrame::INTERNAL); FrameAndConstantPoolScope scope(masm, StackFrame::INTERNAL);
// Push a copy of the function onto the stack. // Push a copy of the function onto the stack.
__ push(r1); __ push(r1);
// Push function as parameter to the runtime call. // Push function as parameter to the runtime call.
...@@ -353,7 +353,7 @@ static void Generate_JSConstructStubHelper(MacroAssembler* masm, ...@@ -353,7 +353,7 @@ static void Generate_JSConstructStubHelper(MacroAssembler* masm,
// Enter a construct frame. // Enter a construct frame.
{ {
FrameScope scope(masm, StackFrame::CONSTRUCT); FrameAndConstantPoolScope scope(masm, StackFrame::CONSTRUCT);
// Preserve the two incoming parameters on the stack. // Preserve the two incoming parameters on the stack.
__ SmiTag(r0); __ SmiTag(r0);
...@@ -773,7 +773,7 @@ void Builtins::Generate_CompileUnoptimized(MacroAssembler* masm) { ...@@ -773,7 +773,7 @@ void Builtins::Generate_CompileUnoptimized(MacroAssembler* masm) {
static void CallCompileOptimized(MacroAssembler* masm, bool concurrent) { static void CallCompileOptimized(MacroAssembler* masm, bool concurrent) {
FrameScope scope(masm, StackFrame::INTERNAL); FrameAndConstantPoolScope scope(masm, StackFrame::INTERNAL);
// Push a copy of the function onto the stack. // Push a copy of the function onto the stack.
__ push(r1); __ push(r1);
// Push function as parameter to the runtime call. // Push function as parameter to the runtime call.
...@@ -869,7 +869,7 @@ void Builtins::Generate_MarkCodeAsExecutedTwice(MacroAssembler* masm) { ...@@ -869,7 +869,7 @@ void Builtins::Generate_MarkCodeAsExecutedTwice(MacroAssembler* masm) {
static void Generate_NotifyStubFailureHelper(MacroAssembler* masm, static void Generate_NotifyStubFailureHelper(MacroAssembler* masm,
SaveFPRegsMode save_doubles) { SaveFPRegsMode save_doubles) {
{ {
FrameScope scope(masm, StackFrame::INTERNAL); FrameAndConstantPoolScope scope(masm, StackFrame::INTERNAL);
// Preserve registers across notification, this is important for compiled // Preserve registers across notification, this is important for compiled
// stubs that tail call the runtime on deopts passing their parameters in // stubs that tail call the runtime on deopts passing their parameters in
...@@ -898,7 +898,7 @@ void Builtins::Generate_NotifyStubFailureSaveDoubles(MacroAssembler* masm) { ...@@ -898,7 +898,7 @@ void Builtins::Generate_NotifyStubFailureSaveDoubles(MacroAssembler* masm) {
static void Generate_NotifyDeoptimizedHelper(MacroAssembler* masm, static void Generate_NotifyDeoptimizedHelper(MacroAssembler* masm,
Deoptimizer::BailoutType type) { Deoptimizer::BailoutType type) {
{ {
FrameScope scope(masm, StackFrame::INTERNAL); FrameAndConstantPoolScope scope(masm, StackFrame::INTERNAL);
// Pass the function and deoptimization type to the runtime system. // Pass the function and deoptimization type to the runtime system.
__ mov(r0, Operand(Smi::FromInt(static_cast<int>(type)))); __ mov(r0, Operand(Smi::FromInt(static_cast<int>(type))));
__ push(r0); __ push(r0);
...@@ -946,7 +946,7 @@ void Builtins::Generate_OnStackReplacement(MacroAssembler* masm) { ...@@ -946,7 +946,7 @@ void Builtins::Generate_OnStackReplacement(MacroAssembler* masm) {
// Lookup the function in the JavaScript frame. // Lookup the function in the JavaScript frame.
__ ldr(r0, MemOperand(fp, JavaScriptFrameConstants::kFunctionOffset)); __ ldr(r0, MemOperand(fp, JavaScriptFrameConstants::kFunctionOffset));
{ {
FrameScope scope(masm, StackFrame::INTERNAL); FrameAndConstantPoolScope scope(masm, StackFrame::INTERNAL);
// Pass function as argument. // Pass function as argument.
__ push(r0); __ push(r0);
__ CallRuntime(Runtime::kCompileForOnStackReplacement, 1); __ CallRuntime(Runtime::kCompileForOnStackReplacement, 1);
...@@ -986,7 +986,7 @@ void Builtins::Generate_OsrAfterStackCheck(MacroAssembler* masm) { ...@@ -986,7 +986,7 @@ void Builtins::Generate_OsrAfterStackCheck(MacroAssembler* masm) {
__ cmp(sp, Operand(ip)); __ cmp(sp, Operand(ip));
__ b(hs, &ok); __ b(hs, &ok);
{ {
FrameScope scope(masm, StackFrame::INTERNAL); FrameAndConstantPoolScope scope(masm, StackFrame::INTERNAL);
__ CallRuntime(Runtime::kStackGuard, 0); __ CallRuntime(Runtime::kStackGuard, 0);
} }
__ Jump(masm->isolate()->builtins()->OnStackReplacement(), __ Jump(masm->isolate()->builtins()->OnStackReplacement(),
...@@ -1061,7 +1061,7 @@ void Builtins::Generate_FunctionCall(MacroAssembler* masm) { ...@@ -1061,7 +1061,7 @@ void Builtins::Generate_FunctionCall(MacroAssembler* masm) {
{ {
// Enter an internal frame in order to preserve argument count. // Enter an internal frame in order to preserve argument count.
FrameScope scope(masm, StackFrame::INTERNAL); FrameAndConstantPoolScope scope(masm, StackFrame::INTERNAL);
__ SmiTag(r0); __ SmiTag(r0);
__ push(r0); __ push(r0);
...@@ -1188,7 +1188,7 @@ void Builtins::Generate_FunctionApply(MacroAssembler* masm) { ...@@ -1188,7 +1188,7 @@ void Builtins::Generate_FunctionApply(MacroAssembler* masm) {
const int kFunctionOffset = 4 * kPointerSize; const int kFunctionOffset = 4 * kPointerSize;
{ {
FrameScope frame_scope(masm, StackFrame::INTERNAL); FrameAndConstantPoolScope frame_scope(masm, StackFrame::INTERNAL);
__ ldr(r0, MemOperand(fp, kFunctionOffset)); // get the function __ ldr(r0, MemOperand(fp, kFunctionOffset)); // get the function
__ push(r0); __ push(r0);
......
...@@ -490,7 +490,7 @@ void HydrogenCodeStub::GenerateLightweightMiss(MacroAssembler* masm) { ...@@ -490,7 +490,7 @@ void HydrogenCodeStub::GenerateLightweightMiss(MacroAssembler* masm) {
int param_count = descriptor->register_param_count_; int param_count = descriptor->register_param_count_;
{ {
// Call the runtime system in a fresh internal frame. // Call the runtime system in a fresh internal frame.
FrameScope scope(masm, StackFrame::INTERNAL); FrameAndConstantPoolScope scope(masm, StackFrame::INTERNAL);
ASSERT(descriptor->register_param_count_ == 0 || ASSERT(descriptor->register_param_count_ == 0 ||
r0.is(descriptor->register_params_[param_count - 1])); r0.is(descriptor->register_params_[param_count - 1]));
// Push arguments // Push arguments
...@@ -1606,14 +1606,15 @@ void CEntryStub::GenerateCore(MacroAssembler* masm, ...@@ -1606,14 +1606,15 @@ void CEntryStub::GenerateCore(MacroAssembler* masm,
JumpIfOOM(masm, r0, ip, throw_out_of_memory_exception); JumpIfOOM(masm, r0, ip, throw_out_of_memory_exception);
// Clear the pending exception. // Clear the pending exception.
__ mov(r3, Operand(isolate->factory()->the_hole_value())); __ LoadRoot(r3, Heap::kTheHoleValueRootIndex);
__ mov(ip, Operand(ExternalReference(Isolate::kPendingExceptionAddress, __ mov(ip, Operand(ExternalReference(Isolate::kPendingExceptionAddress,
isolate))); isolate)));
__ str(r3, MemOperand(ip)); __ str(r3, MemOperand(ip));
// Special handling of termination exceptions which are uncatchable // Special handling of termination exceptions which are uncatchable
// by javascript code. // by javascript code.
__ cmp(r0, Operand(isolate->factory()->termination_exception())); __ LoadRoot(r3, Heap::kTerminationExceptionRootIndex);
__ cmp(r0, r3);
__ b(eq, throw_termination_exception); __ b(eq, throw_termination_exception);
// Handle normal exception. // Handle normal exception.
...@@ -1645,7 +1646,7 @@ void CEntryStub::Generate(MacroAssembler* masm) { ...@@ -1645,7 +1646,7 @@ void CEntryStub::Generate(MacroAssembler* masm) {
__ sub(r6, r6, Operand(kPointerSize)); __ sub(r6, r6, Operand(kPointerSize));
// Enter the exit frame that transitions from JavaScript to C++. // Enter the exit frame that transitions from JavaScript to C++.
FrameScope scope(masm, StackFrame::MANUAL); FrameAndConstantPoolScope scope(masm, StackFrame::MANUAL);
__ EnterExitFrame(save_doubles_); __ EnterExitFrame(save_doubles_);
// Set up argc and the builtin function in callee-saved registers. // Set up argc and the builtin function in callee-saved registers.
...@@ -2057,7 +2058,7 @@ void InstanceofStub::Generate(MacroAssembler* masm) { ...@@ -2057,7 +2058,7 @@ void InstanceofStub::Generate(MacroAssembler* masm) {
__ InvokeBuiltin(Builtins::INSTANCE_OF, JUMP_FUNCTION); __ InvokeBuiltin(Builtins::INSTANCE_OF, JUMP_FUNCTION);
} else { } else {
{ {
FrameScope scope(masm, StackFrame::INTERNAL); FrameAndConstantPoolScope scope(masm, StackFrame::INTERNAL);
__ Push(r0, r1); __ Push(r0, r1);
__ InvokeBuiltin(Builtins::INSTANCE_OF, CALL_FUNCTION); __ InvokeBuiltin(Builtins::INSTANCE_OF, CALL_FUNCTION);
} }
...@@ -3066,7 +3067,7 @@ static void GenerateRecordCallTarget(MacroAssembler* masm) { ...@@ -3066,7 +3067,7 @@ static void GenerateRecordCallTarget(MacroAssembler* masm) {
// The target function is the Array constructor, // The target function is the Array constructor,
// Create an AllocationSite if we don't already have it, store it in the slot. // Create an AllocationSite if we don't already have it, store it in the slot.
{ {
FrameScope scope(masm, StackFrame::INTERNAL); FrameAndConstantPoolScope scope(masm, StackFrame::INTERNAL);
// Arguments register must be smi-tagged to call out. // Arguments register must be smi-tagged to call out.
__ SmiTag(r0); __ SmiTag(r0);
...@@ -3189,7 +3190,7 @@ void CallFunctionStub::Generate(MacroAssembler* masm) { ...@@ -3189,7 +3190,7 @@ void CallFunctionStub::Generate(MacroAssembler* masm) {
if (CallAsMethod()) { if (CallAsMethod()) {
__ bind(&wrap); __ bind(&wrap);
// Wrap the receiver and patch it back onto the stack. // Wrap the receiver and patch it back onto the stack.
{ FrameScope frame_scope(masm, StackFrame::INTERNAL); { FrameAndConstantPoolScope frame_scope(masm, StackFrame::INTERNAL);
__ Push(r1, r3); __ Push(r1, r3);
__ InvokeBuiltin(Builtins::TO_OBJECT, CALL_FUNCTION); __ InvokeBuiltin(Builtins::TO_OBJECT, CALL_FUNCTION);
__ pop(r1); __ pop(r1);
...@@ -4474,7 +4475,7 @@ void ICCompareStub::GenerateMiss(MacroAssembler* masm) { ...@@ -4474,7 +4475,7 @@ void ICCompareStub::GenerateMiss(MacroAssembler* masm) {
ExternalReference miss = ExternalReference miss =
ExternalReference(IC_Utility(IC::kCompareIC_Miss), masm->isolate()); ExternalReference(IC_Utility(IC::kCompareIC_Miss), masm->isolate());
FrameScope scope(masm, StackFrame::INTERNAL); FrameAndConstantPoolScope scope(masm, StackFrame::INTERNAL);
__ Push(r1, r0); __ Push(r1, r0);
__ Push(lr, r1, r0); __ Push(lr, r1, r0);
__ mov(ip, Operand(Smi::FromInt(op_))); __ mov(ip, Operand(Smi::FromInt(op_)));
...@@ -5496,7 +5497,7 @@ void CallApiFunctionStub::Generate(MacroAssembler* masm) { ...@@ -5496,7 +5497,7 @@ void CallApiFunctionStub::Generate(MacroAssembler* masm) {
// it's not controlled by GC. // it's not controlled by GC.
const int kApiStackSpace = 4; const int kApiStackSpace = 4;
FrameScope frame_scope(masm, StackFrame::MANUAL); FrameAndConstantPoolScope frame_scope(masm, StackFrame::MANUAL);
__ EnterExitFrame(false, kApiStackSpace); __ EnterExitFrame(false, kApiStackSpace);
ASSERT(!api_function_address.is(r0) && !scratch.is(r0)); ASSERT(!api_function_address.is(r0) && !scratch.is(r0));
...@@ -5556,7 +5557,7 @@ void CallApiGetterStub::Generate(MacroAssembler* masm) { ...@@ -5556,7 +5557,7 @@ void CallApiGetterStub::Generate(MacroAssembler* masm) {
__ add(r1, r0, Operand(1 * kPointerSize)); // r1 = PCA __ add(r1, r0, Operand(1 * kPointerSize)); // r1 = PCA
const int kApiStackSpace = 1; const int kApiStackSpace = 1;
FrameScope frame_scope(masm, StackFrame::MANUAL); FrameAndConstantPoolScope frame_scope(masm, StackFrame::MANUAL);
__ EnterExitFrame(false, kApiStackSpace); __ EnterExitFrame(false, kApiStackSpace);
// Create PropertyAccessorInfo instance on the stack above the exit frame with // Create PropertyAccessorInfo instance on the stack above the exit frame with
......
...@@ -117,7 +117,7 @@ static void Generate_DebugBreakCallHelper(MacroAssembler* masm, ...@@ -117,7 +117,7 @@ static void Generate_DebugBreakCallHelper(MacroAssembler* masm,
RegList object_regs, RegList object_regs,
RegList non_object_regs) { RegList non_object_regs) {
{ {
FrameScope scope(masm, StackFrame::INTERNAL); FrameAndConstantPoolScope scope(masm, StackFrame::INTERNAL);
// Store the registers containing live values on the expression stack to // Store the registers containing live values on the expression stack to
// make sure that these are correctly updated during GC. Non object values // make sure that these are correctly updated during GC. Non object values
......
...@@ -171,7 +171,6 @@ void FullCodeGenerator::Generate() { ...@@ -171,7 +171,6 @@ void FullCodeGenerator::Generate() {
info->set_prologue_offset(masm_->pc_offset()); info->set_prologue_offset(masm_->pc_offset());
__ Prologue(BUILD_FUNCTION_FRAME); __ Prologue(BUILD_FUNCTION_FRAME);
info->AddNoFrameRange(0, masm_->pc_offset()); info->AddNoFrameRange(0, masm_->pc_offset());
__ LoadConstantPoolPointerRegister();
{ Comment cmnt(masm_, "[ Allocate locals"); { Comment cmnt(masm_, "[ Allocate locals");
int locals_count = info->scope()->num_stack_slots(); int locals_count = info->scope()->num_stack_slots();
......
...@@ -173,7 +173,6 @@ bool LCodeGen::GeneratePrologue() { ...@@ -173,7 +173,6 @@ bool LCodeGen::GeneratePrologue() {
__ Prologue(info()->IsStub() ? BUILD_STUB_FRAME : BUILD_FUNCTION_FRAME); __ Prologue(info()->IsStub() ? BUILD_STUB_FRAME : BUILD_FUNCTION_FRAME);
frame_is_built_ = true; frame_is_built_ = true;
info_->AddNoFrameRange(0, masm_->pc_offset()); info_->AddNoFrameRange(0, masm_->pc_offset());
__ LoadConstantPoolPointerRegister();
} }
// Reserve space for the stack slots needed by the code. // Reserve space for the stack slots needed by the code.
......
...@@ -888,6 +888,16 @@ void MacroAssembler::VmovLow(DwVfpRegister dst, Register src) { ...@@ -888,6 +888,16 @@ void MacroAssembler::VmovLow(DwVfpRegister dst, Register src) {
} }
void MacroAssembler::LoadConstantPoolPointerRegister() {
if (FLAG_enable_ool_constant_pool) {
int constant_pool_offset = Code::kConstantPoolOffset - Code::kHeaderSize -
pc_offset() - Instruction::kPCReadOffset;
ASSERT(ImmediateFitsAddrMode2Instruction(constant_pool_offset));
ldr(pp, MemOperand(pc, constant_pool_offset));
}
}
void MacroAssembler::Prologue(PrologueFrameMode frame_mode) { void MacroAssembler::Prologue(PrologueFrameMode frame_mode) {
if (frame_mode == BUILD_STUB_FRAME) { if (frame_mode == BUILD_STUB_FRAME) {
PushFixedFrame(); PushFixedFrame();
...@@ -912,22 +922,20 @@ void MacroAssembler::Prologue(PrologueFrameMode frame_mode) { ...@@ -912,22 +922,20 @@ void MacroAssembler::Prologue(PrologueFrameMode frame_mode) {
add(fp, sp, Operand(StandardFrameConstants::kFixedFrameSizeFromFp)); add(fp, sp, Operand(StandardFrameConstants::kFixedFrameSizeFromFp));
} }
} }
}
void MacroAssembler::LoadConstantPoolPointerRegister() {
if (FLAG_enable_ool_constant_pool) { if (FLAG_enable_ool_constant_pool) {
int constant_pool_offset = LoadConstantPoolPointerRegister();
Code::kConstantPoolOffset - Code::kHeaderSize - pc_offset() - 8; set_constant_pool_available(true);
ASSERT(ImmediateFitsAddrMode2Instruction(constant_pool_offset));
ldr(pp, MemOperand(pc, constant_pool_offset));
} }
} }
void MacroAssembler::EnterFrame(StackFrame::Type type) { void MacroAssembler::EnterFrame(StackFrame::Type type,
bool load_constant_pool) {
// r0-r3: preserved // r0-r3: preserved
PushFixedFrame(); PushFixedFrame();
if (FLAG_enable_ool_constant_pool && load_constant_pool) {
LoadConstantPoolPointerRegister();
}
mov(ip, Operand(Smi::FromInt(type))); mov(ip, Operand(Smi::FromInt(type)));
push(ip); push(ip);
mov(ip, Operand(CodeObject())); mov(ip, Operand(CodeObject()));
...@@ -975,6 +983,7 @@ void MacroAssembler::EnterExitFrame(bool save_doubles, int stack_space) { ...@@ -975,6 +983,7 @@ void MacroAssembler::EnterExitFrame(bool save_doubles, int stack_space) {
} }
if (FLAG_enable_ool_constant_pool) { if (FLAG_enable_ool_constant_pool) {
str(pp, MemOperand(fp, ExitFrameConstants::kConstantPoolOffset)); str(pp, MemOperand(fp, ExitFrameConstants::kConstantPoolOffset));
LoadConstantPoolPointerRegister();
} }
mov(ip, Operand(CodeObject())); mov(ip, Operand(CodeObject()));
str(ip, MemOperand(fp, ExitFrameConstants::kCodeOffset)); str(ip, MemOperand(fp, ExitFrameConstants::kCodeOffset));
......
...@@ -540,9 +540,6 @@ class MacroAssembler: public Assembler { ...@@ -540,9 +540,6 @@ class MacroAssembler: public Assembler {
// Generates function and stub prologue code. // Generates function and stub prologue code.
void Prologue(PrologueFrameMode frame_mode); void Prologue(PrologueFrameMode frame_mode);
// Loads the constant pool pointer (pp) register.
void LoadConstantPoolPointerRegister();
// Enter exit frame. // Enter exit frame.
// stack_space - extra stack space, used for alignment before call to C. // stack_space - extra stack space, used for alignment before call to C.
void EnterExitFrame(bool save_doubles, int stack_space = 0); void EnterExitFrame(bool save_doubles, int stack_space = 0);
...@@ -1387,7 +1384,7 @@ class MacroAssembler: public Assembler { ...@@ -1387,7 +1384,7 @@ class MacroAssembler: public Assembler {
} }
// Activation support. // Activation support.
void EnterFrame(StackFrame::Type type); void EnterFrame(StackFrame::Type type, bool load_constant_pool = false);
// Returns the pc offset at which the frame ends. // Returns the pc offset at which the frame ends.
int LeaveFrame(StackFrame::Type type); int LeaveFrame(StackFrame::Type type);
...@@ -1464,6 +1461,9 @@ class MacroAssembler: public Assembler { ...@@ -1464,6 +1461,9 @@ class MacroAssembler: public Assembler {
MemOperand SafepointRegisterSlot(Register reg); MemOperand SafepointRegisterSlot(Register reg);
MemOperand SafepointRegistersAndDoublesSlot(Register reg); MemOperand SafepointRegistersAndDoublesSlot(Register reg);
// Loads the constant pool pointer (pp) register.
void LoadConstantPoolPointerRegister();
bool generating_stub_; bool generating_stub_;
bool has_frame_; bool has_frame_;
// This handle will be patched with the code object on installation. // This handle will be patched with the code object on installation.
...@@ -1513,6 +1513,70 @@ class CodePatcher { ...@@ -1513,6 +1513,70 @@ class CodePatcher {
}; };
class FrameAndConstantPoolScope {
public:
FrameAndConstantPoolScope(MacroAssembler* masm, StackFrame::Type type)
: masm_(masm),
type_(type),
old_has_frame_(masm->has_frame()),
old_constant_pool_available_(masm->is_constant_pool_available()) {
masm->set_has_frame(true);
masm->set_constant_pool_available(true);
if (type_ != StackFrame::MANUAL && type_ != StackFrame::NONE) {
masm->EnterFrame(type, !old_constant_pool_available_);
}
}
~FrameAndConstantPoolScope() {
masm_->LeaveFrame(type_);
masm_->set_has_frame(old_has_frame_);
masm_->set_constant_pool_available(old_constant_pool_available_);
}
// Normally we generate the leave-frame code when this object goes
// out of scope. Sometimes we may need to generate the code somewhere else
// in addition. Calling this will achieve that, but the object stays in
// scope, the MacroAssembler is still marked as being in a frame scope, and
// the code will be generated again when it goes out of scope.
void GenerateLeaveFrame() {
ASSERT(type_ != StackFrame::MANUAL && type_ != StackFrame::NONE);
masm_->LeaveFrame(type_);
}
private:
MacroAssembler* masm_;
StackFrame::Type type_;
bool old_has_frame_;
bool old_constant_pool_available_;
DISALLOW_IMPLICIT_CONSTRUCTORS(FrameAndConstantPoolScope);
};
// Class for scoping the the unavailability of constant pool access.
class ConstantPoolUnavailableScope {
public:
explicit ConstantPoolUnavailableScope(MacroAssembler* masm)
: masm_(masm),
old_constant_pool_available_(masm->is_constant_pool_available()) {
if (FLAG_enable_ool_constant_pool) {
masm_->set_constant_pool_available(false);
}
}
~ConstantPoolUnavailableScope() {
if (FLAG_enable_ool_constant_pool) {
masm_->set_constant_pool_available(old_constant_pool_available_);
}
}
private:
MacroAssembler* masm_;
int old_constant_pool_available_;
DISALLOW_IMPLICIT_CONSTRUCTORS(ConstantPoolUnavailableScope);
};
// ----------------------------------------------------------------------------- // -----------------------------------------------------------------------------
// Static helper functions. // Static helper functions.
......
...@@ -1162,7 +1162,7 @@ void LoadStubCompiler::GenerateLoadInterceptor( ...@@ -1162,7 +1162,7 @@ void LoadStubCompiler::GenerateLoadInterceptor(
// Save necessary data before invoking an interceptor. // Save necessary data before invoking an interceptor.
// Requires a frame to make GC aware of pushed pointers. // Requires a frame to make GC aware of pushed pointers.
{ {
FrameScope frame_scope(masm(), StackFrame::INTERNAL); FrameAndConstantPoolScope frame_scope(masm(), StackFrame::INTERNAL);
if (must_preserve_receiver_reg) { if (must_preserve_receiver_reg) {
__ Push(receiver(), holder_reg, this->name()); __ Push(receiver(), holder_reg, this->name());
} else { } else {
...@@ -1262,7 +1262,7 @@ void StoreStubCompiler::GenerateStoreViaSetter( ...@@ -1262,7 +1262,7 @@ void StoreStubCompiler::GenerateStoreViaSetter(
// -- lr : return address // -- lr : return address
// ----------------------------------- // -----------------------------------
{ {
FrameScope scope(masm, StackFrame::INTERNAL); FrameAndConstantPoolScope scope(masm, StackFrame::INTERNAL);
// Save value register, so we can restore it later. // Save value register, so we can restore it later.
__ push(value()); __ push(value());
...@@ -1377,7 +1377,7 @@ void LoadStubCompiler::GenerateLoadViaGetter(MacroAssembler* masm, ...@@ -1377,7 +1377,7 @@ void LoadStubCompiler::GenerateLoadViaGetter(MacroAssembler* masm,
// -- lr : return address // -- lr : return address
// ----------------------------------- // -----------------------------------
{ {
FrameScope scope(masm, StackFrame::INTERNAL); FrameAndConstantPoolScope scope(masm, StackFrame::INTERNAL);
if (!getter.is_null()) { if (!getter.is_null()) {
// Call the JavaScript getter with the receiver on the stack. // Call the JavaScript getter with the receiver on the stack.
......
...@@ -124,6 +124,7 @@ class FrameScope { ...@@ -124,6 +124,7 @@ class FrameScope {
// scope, the MacroAssembler is still marked as being in a frame scope, and // scope, the MacroAssembler is still marked as being in a frame scope, and
// the code will be generated again when it goes out of scope. // the code will be generated again when it goes out of scope.
void GenerateLeaveFrame() { void GenerateLeaveFrame() {
ASSERT(type_ != StackFrame::MANUAL && type_ != StackFrame::NONE);
masm_->LeaveFrame(type_); masm_->LeaveFrame(type_);
} }
......
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