Revision: 19858
Author: [email protected]
Date: Wed Mar 12 15:56:16 2014 UTC
Log: 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.
[email protected], [email protected]
Review URL: https://codereview.chromium.org/190793002
http://code.google.com/p/v8/source/detail?r=19858
Modified:
/branches/bleeding_edge/src/arm/assembler-arm.cc
/branches/bleeding_edge/src/arm/assembler-arm.h
/branches/bleeding_edge/src/arm/builtins-arm.cc
/branches/bleeding_edge/src/arm/code-stubs-arm.cc
/branches/bleeding_edge/src/arm/debug-arm.cc
/branches/bleeding_edge/src/arm/full-codegen-arm.cc
/branches/bleeding_edge/src/arm/lithium-codegen-arm.cc
/branches/bleeding_edge/src/arm/macro-assembler-arm.cc
/branches/bleeding_edge/src/arm/macro-assembler-arm.h
/branches/bleeding_edge/src/arm/stub-cache-arm.cc
/branches/bleeding_edge/src/macro-assembler.h
=======================================
--- /branches/bleeding_edge/src/arm/assembler-arm.cc Tue Mar 11 20:17:02
2014 UTC
+++ /branches/bleeding_edge/src/arm/assembler-arm.cc Wed Mar 12 15:56:16
2014 UTC
@@ -530,6 +530,8 @@
first_const_pool_32_use_ = -1;
first_const_pool_64_use_ = -1;
last_bound_pos_ = 0;
+ constant_pool_available_ = !FLAG_enable_ool_constant_pool;
+ constant_pool_full_ = false;
ClearRecordedAstId();
}
=======================================
--- /branches/bleeding_edge/src/arm/assembler-arm.h Wed Mar 12 15:23:54
2014 UTC
+++ /branches/bleeding_edge/src/arm/assembler-arm.h Wed Mar 12 15:56:16
2014 UTC
@@ -1458,6 +1458,14 @@
// Check if is time to emit a constant pool.
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:
// 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
@@ -1510,6 +1518,14 @@
return (const_pool_blocked_nesting_ > 0) ||
(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:
int next_buffer_check_; // pc offset of next buffer check
@@ -1571,6 +1587,13 @@
// The bound position, before this we cannot do instruction elimination.
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
inline void CheckBuffer();
void GrowBuffer();
@@ -1607,6 +1630,8 @@
friend class RelocInfo;
friend class CodePatcher;
friend class BlockConstPoolScope;
+ friend class FrameAndConstantPoolScope;
+ friend class ConstantPoolUnavailableScope;
PositionsRecorder positions_recorder_;
friend class PositionsRecorder;
=======================================
--- /branches/bleeding_edge/src/arm/builtins-arm.cc Tue Mar 11 14:39:08
2014 UTC
+++ /branches/bleeding_edge/src/arm/builtins-arm.cc Wed Mar 12 15:56:16
2014 UTC
@@ -261,7 +261,7 @@
__ push(function); // Preserve the function.
__ IncrementCounter(counters->string_ctor_conversions(), 1, r3, r4);
{
- FrameScope scope(masm, StackFrame::INTERNAL);
+ FrameAndConstantPoolScope scope(masm, StackFrame::INTERNAL);
__ push(r0);
__ InvokeBuiltin(Builtins::TO_STRING, CALL_FUNCTION);
}
@@ -281,7 +281,7 @@
__ bind(&gc_required);
__ IncrementCounter(counters->string_ctor_gc_required(), 1, r3, r4);
{
- FrameScope scope(masm, StackFrame::INTERNAL);
+ FrameAndConstantPoolScope scope(masm, StackFrame::INTERNAL);
__ push(argument);
__ CallRuntime(Runtime::kNewStringWrapper, 1);
}
@@ -291,7 +291,7 @@
static void CallRuntimePassFunction(
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(r1);
// Push function as parameter to the runtime call.
@@ -353,7 +353,7 @@
// Enter a construct frame.
{
- FrameScope scope(masm, StackFrame::CONSTRUCT);
+ FrameAndConstantPoolScope scope(masm, StackFrame::CONSTRUCT);
// Preserve the two incoming parameters on the stack.
__ SmiTag(r0);
@@ -773,7 +773,7 @@
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(r1);
// Push function as parameter to the runtime call.
@@ -869,7 +869,7 @@
static void Generate_NotifyStubFailureHelper(MacroAssembler* masm,
SaveFPRegsMode save_doubles) {
{
- FrameScope scope(masm, StackFrame::INTERNAL);
+ FrameAndConstantPoolScope scope(masm, StackFrame::INTERNAL);
// Preserve registers across notification, this is important for
compiled
// stubs that tail call the runtime on deopts passing their parameters
in
@@ -898,7 +898,7 @@
static void Generate_NotifyDeoptimizedHelper(MacroAssembler* masm,
Deoptimizer::BailoutType
type) {
{
- FrameScope scope(masm, StackFrame::INTERNAL);
+ FrameAndConstantPoolScope scope(masm, StackFrame::INTERNAL);
// Pass the function and deoptimization type to the runtime system.
__ mov(r0, Operand(Smi::FromInt(static_cast<int>(type))));
__ push(r0);
@@ -946,7 +946,7 @@
// Lookup the function in the JavaScript frame.
__ ldr(r0, MemOperand(fp, JavaScriptFrameConstants::kFunctionOffset));
{
- FrameScope scope(masm, StackFrame::INTERNAL);
+ FrameAndConstantPoolScope scope(masm, StackFrame::INTERNAL);
// Pass function as argument.
__ push(r0);
__ CallRuntime(Runtime::kCompileForOnStackReplacement, 1);
@@ -986,7 +986,7 @@
__ cmp(sp, Operand(ip));
__ b(hs, &ok);
{
- FrameScope scope(masm, StackFrame::INTERNAL);
+ FrameAndConstantPoolScope scope(masm, StackFrame::INTERNAL);
__ CallRuntime(Runtime::kStackGuard, 0);
}
__ Jump(masm->isolate()->builtins()->OnStackReplacement(),
@@ -1061,7 +1061,7 @@
{
// Enter an internal frame in order to preserve argument count.
- FrameScope scope(masm, StackFrame::INTERNAL);
+ FrameAndConstantPoolScope scope(masm, StackFrame::INTERNAL);
__ SmiTag(r0);
__ push(r0);
@@ -1188,7 +1188,7 @@
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
__ push(r0);
=======================================
--- /branches/bleeding_edge/src/arm/code-stubs-arm.cc Tue Mar 11 14:41:22
2014 UTC
+++ /branches/bleeding_edge/src/arm/code-stubs-arm.cc Wed Mar 12 15:56:16
2014 UTC
@@ -490,7 +490,7 @@
int param_count = descriptor->register_param_count_;
{
// 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 ||
r0.is(descriptor->register_params_[param_count - 1]));
// Push arguments
@@ -1606,14 +1606,15 @@
JumpIfOOM(masm, r0, ip, throw_out_of_memory_exception);
// Clear the pending exception.
- __ mov(r3, Operand(isolate->factory()->the_hole_value()));
+ __ LoadRoot(r3, Heap::kTheHoleValueRootIndex);
__ mov(ip, Operand(ExternalReference(Isolate::kPendingExceptionAddress,
isolate)));
__ str(r3, MemOperand(ip));
// Special handling of termination exceptions which are uncatchable
// by javascript code.
- __ cmp(r0, Operand(isolate->factory()->termination_exception()));
+ __ LoadRoot(r3, Heap::kTerminationExceptionRootIndex);
+ __ cmp(r0, r3);
__ b(eq, throw_termination_exception);
// Handle normal exception.
@@ -1645,7 +1646,7 @@
__ sub(r6, r6, Operand(kPointerSize));
// Enter the exit frame that transitions from JavaScript to C++.
- FrameScope scope(masm, StackFrame::MANUAL);
+ FrameAndConstantPoolScope scope(masm, StackFrame::MANUAL);
__ EnterExitFrame(save_doubles_);
// Set up argc and the builtin function in callee-saved registers.
@@ -2057,7 +2058,7 @@
__ InvokeBuiltin(Builtins::INSTANCE_OF, JUMP_FUNCTION);
} else {
{
- FrameScope scope(masm, StackFrame::INTERNAL);
+ FrameAndConstantPoolScope scope(masm, StackFrame::INTERNAL);
__ Push(r0, r1);
__ InvokeBuiltin(Builtins::INSTANCE_OF, CALL_FUNCTION);
}
@@ -3066,7 +3067,7 @@
// The target function is the Array constructor,
// 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.
__ SmiTag(r0);
@@ -3189,7 +3190,7 @@
if (CallAsMethod()) {
__ bind(&wrap);
// 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);
__ InvokeBuiltin(Builtins::TO_OBJECT, CALL_FUNCTION);
__ pop(r1);
@@ -4474,7 +4475,7 @@
ExternalReference miss =
ExternalReference(IC_Utility(IC::kCompareIC_Miss),
masm->isolate());
- FrameScope scope(masm, StackFrame::INTERNAL);
+ FrameAndConstantPoolScope scope(masm, StackFrame::INTERNAL);
__ Push(r1, r0);
__ Push(lr, r1, r0);
__ mov(ip, Operand(Smi::FromInt(op_)));
@@ -5496,7 +5497,7 @@
// it's not controlled by GC.
const int kApiStackSpace = 4;
- FrameScope frame_scope(masm, StackFrame::MANUAL);
+ FrameAndConstantPoolScope frame_scope(masm, StackFrame::MANUAL);
__ EnterExitFrame(false, kApiStackSpace);
ASSERT(!api_function_address.is(r0) && !scratch.is(r0));
@@ -5556,7 +5557,7 @@
__ add(r1, r0, Operand(1 * kPointerSize)); // r1 = PCA
const int kApiStackSpace = 1;
- FrameScope frame_scope(masm, StackFrame::MANUAL);
+ FrameAndConstantPoolScope frame_scope(masm, StackFrame::MANUAL);
__ EnterExitFrame(false, kApiStackSpace);
// Create PropertyAccessorInfo instance on the stack above the exit
frame with
=======================================
--- /branches/bleeding_edge/src/arm/debug-arm.cc Mon Feb 10 21:38:17 2014
UTC
+++ /branches/bleeding_edge/src/arm/debug-arm.cc Wed Mar 12 15:56:16 2014
UTC
@@ -117,7 +117,7 @@
RegList 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
// make sure that these are correctly updated during GC. Non object
values
=======================================
--- /branches/bleeding_edge/src/arm/full-codegen-arm.cc Tue Mar 11 14:41:22
2014 UTC
+++ /branches/bleeding_edge/src/arm/full-codegen-arm.cc Wed Mar 12 15:56:16
2014 UTC
@@ -171,7 +171,6 @@
info->set_prologue_offset(masm_->pc_offset());
__ Prologue(BUILD_FUNCTION_FRAME);
info->AddNoFrameRange(0, masm_->pc_offset());
- __ LoadConstantPoolPointerRegister();
{ Comment cmnt(masm_, "[ Allocate locals");
int locals_count = info->scope()->num_stack_slots();
=======================================
--- /branches/bleeding_edge/src/arm/lithium-codegen-arm.cc Wed Mar 12
14:06:26 2014 UTC
+++ /branches/bleeding_edge/src/arm/lithium-codegen-arm.cc Wed Mar 12
15:56:16 2014 UTC
@@ -173,7 +173,6 @@
__ Prologue(info()->IsStub() ? BUILD_STUB_FRAME :
BUILD_FUNCTION_FRAME);
frame_is_built_ = true;
info_->AddNoFrameRange(0, masm_->pc_offset());
- __ LoadConstantPoolPointerRegister();
}
// Reserve space for the stack slots needed by the code.
=======================================
--- /branches/bleeding_edge/src/arm/macro-assembler-arm.cc Mon Mar 10
10:39:17 2014 UTC
+++ /branches/bleeding_edge/src/arm/macro-assembler-arm.cc Wed Mar 12
15:56:16 2014 UTC
@@ -886,6 +886,16 @@
vmov(dst, VmovIndexLo, 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) {
@@ -912,22 +922,20 @@
add(fp, sp, Operand(StandardFrameConstants::kFixedFrameSizeFromFp));
}
}
-}
-
-
-void MacroAssembler::LoadConstantPoolPointerRegister() {
if (FLAG_enable_ool_constant_pool) {
- int constant_pool_offset =
- Code::kConstantPoolOffset - Code::kHeaderSize - pc_offset() - 8;
- ASSERT(ImmediateFitsAddrMode2Instruction(constant_pool_offset));
- ldr(pp, MemOperand(pc, constant_pool_offset));
+ LoadConstantPoolPointerRegister();
+ set_constant_pool_available(true);
}
}
-void MacroAssembler::EnterFrame(StackFrame::Type type) {
+void MacroAssembler::EnterFrame(StackFrame::Type type,
+ bool load_constant_pool) {
// r0-r3: preserved
PushFixedFrame();
+ if (FLAG_enable_ool_constant_pool && load_constant_pool) {
+ LoadConstantPoolPointerRegister();
+ }
mov(ip, Operand(Smi::FromInt(type)));
push(ip);
mov(ip, Operand(CodeObject()));
@@ -975,6 +983,7 @@
}
if (FLAG_enable_ool_constant_pool) {
str(pp, MemOperand(fp, ExitFrameConstants::kConstantPoolOffset));
+ LoadConstantPoolPointerRegister();
}
mov(ip, Operand(CodeObject()));
str(ip, MemOperand(fp, ExitFrameConstants::kCodeOffset));
=======================================
--- /branches/bleeding_edge/src/arm/macro-assembler-arm.h Mon Mar 10
10:39:17 2014 UTC
+++ /branches/bleeding_edge/src/arm/macro-assembler-arm.h Wed Mar 12
15:56:16 2014 UTC
@@ -540,9 +540,6 @@
// Generates function and stub prologue code.
void Prologue(PrologueFrameMode frame_mode);
- // Loads the constant pool pointer (pp) register.
- void LoadConstantPoolPointerRegister();
-
// Enter exit frame.
// stack_space - extra stack space, used for alignment before call to C.
void EnterExitFrame(bool save_doubles, int stack_space = 0);
@@ -1387,7 +1384,7 @@
}
// 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.
int LeaveFrame(StackFrame::Type type);
@@ -1464,6 +1461,9 @@
MemOperand SafepointRegisterSlot(Register reg);
MemOperand SafepointRegistersAndDoublesSlot(Register reg);
+ // Loads the constant pool pointer (pp) register.
+ void LoadConstantPoolPointerRegister();
+
bool generating_stub_;
bool has_frame_;
// This handle will be patched with the code object on installation.
@@ -1513,6 +1513,70 @@
};
+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.
=======================================
--- /branches/bleeding_edge/src/arm/stub-cache-arm.cc Mon Mar 10 12:23:05
2014 UTC
+++ /branches/bleeding_edge/src/arm/stub-cache-arm.cc Wed Mar 12 15:56:16
2014 UTC
@@ -1162,7 +1162,7 @@
// Save necessary data before invoking an interceptor.
// 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) {
__ Push(receiver(), holder_reg, this->name());
} else {
@@ -1262,7 +1262,7 @@
// -- lr : return address
// -----------------------------------
{
- FrameScope scope(masm, StackFrame::INTERNAL);
+ FrameAndConstantPoolScope scope(masm, StackFrame::INTERNAL);
// Save value register, so we can restore it later.
__ push(value());
@@ -1377,7 +1377,7 @@
// -- lr : return address
// -----------------------------------
{
- FrameScope scope(masm, StackFrame::INTERNAL);
+ FrameAndConstantPoolScope scope(masm, StackFrame::INTERNAL);
if (!getter.is_null()) {
// Call the JavaScript getter with the receiver on the stack.
=======================================
--- /branches/bleeding_edge/src/macro-assembler.h Wed Feb 12 09:19:30 2014
UTC
+++ /branches/bleeding_edge/src/macro-assembler.h Wed Mar 12 15:56:16 2014
UTC
@@ -124,6 +124,7 @@
// 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_);
}
--
--
v8-dev mailing list
[email protected]
http://groups.google.com/group/v8-dev
---
You received this message because you are subscribed to the Google Groups "v8-dev" group.
To unsubscribe from this group and stop receiving emails from it, send an email
to [email protected].
For more options, visit https://groups.google.com/d/optout.