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.

Reply via email to