Add the possibility for a code stub to be non-movable
authorsgjesse@chromium.org <sgjesse@chromium.org@ce2b1a6d-e550-0410-aec6-3dcde31c8c00>
Wed, 9 Mar 2011 10:38:19 +0000 (10:38 +0000)
committersgjesse@chromium.org <sgjesse@chromium.org@ce2b1a6d-e550-0410-aec6-3dcde31c8c00>
Wed, 9 Mar 2011 10:38:19 +0000 (10:38 +0000)
Non-moveable code-stube are allocated in large object space. They are only required on ARM where the different C-entry stubs are required to never move.

This gets rid of pre-computing these stubs and hope that they never move. Also for crankshaft the C-entry stub which saved doubles is not generated in the snapshot so it ends up being generated at runtime and potentially move.
Review URL: http://codereview.chromium.org/6626072

git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@7097 ce2b1a6d-e550-0410-aec6-3dcde31c8c00

src/arm/code-stubs-arm.cc
src/arm/code-stubs-arm.h
src/code-stubs.cc
src/code-stubs.h
src/factory.cc
src/factory.h
src/heap.cc
src/heap.h
src/ia32/code-stubs-ia32.cc
src/x64/code-stubs-x64.cc

index 68f9b15..f2cf9f0 100644 (file)
@@ -4156,6 +4156,11 @@ void MathPowStub::Generate(MacroAssembler* masm) {
 }
 
 
+bool CEntryStub::NeedsImmovableCode() {
+  return true;
+}
+
+
 void CEntryStub::GenerateThrowTOS(MacroAssembler* masm) {
   __ Throw(r0);
 }
index e3ef339..b488f67 100644 (file)
@@ -588,6 +588,9 @@ class RegExpCEntryStub: public CodeStub {
  private:
   Major MajorKey() { return RegExpCEntry; }
   int MinorKey() { return 0; }
+
+  bool NeedsImmovableCode() { return true; }
+
   const char* GetName() { return "RegExpCEntryStub"; }
 };
 
@@ -607,6 +610,9 @@ class DirectCEntryStub: public CodeStub {
  private:
   Major MajorKey() { return DirectCEntry; }
   int MinorKey() { return 0; }
+
+  bool NeedsImmovableCode() { return true; }
+
   const char* GetName() { return "DirectCEntryStub"; }
 };
 
index ba77b21..adba2a5 100644 (file)
@@ -101,7 +101,8 @@ Handle<Code> CodeStub::GetCode() {
         static_cast<Code::Kind>(GetCodeKind()),
         InLoop(),
         GetICState());
-    Handle<Code> new_object = Factory::NewCode(desc, flags, masm.CodeObject());
+    Handle<Code> new_object = Factory::NewCode(
+        desc, flags, masm.CodeObject(), NeedsImmovableCode());
     RecordCodeGeneration(*new_object, &masm);
     FinishCode(*new_object);
 
@@ -116,6 +117,7 @@ Handle<Code> CodeStub::GetCode() {
     code = *new_object;
   }
 
+  ASSERT(!NeedsImmovableCode() || Heap::lo_space()->Contains(code));
   return Handle<Code>(code);
 }
 
index 96ac733..f9f7b82 100644 (file)
@@ -167,7 +167,11 @@ class CodeStub BASE_EMBEDDED {
   // Returns a name for logging/debugging purposes.
   virtual const char* GetName() { return MajorName(MajorKey(), false); }
 
-#ifdef DEBUG
+  // Returns whether the code generated for this stub needs to be allocated as
+  // a fixed (non-moveable) code object.
+  virtual bool NeedsImmovableCode() { return false; }
+
+  #ifdef DEBUG
   virtual void Print() { PrintF("%s\n", GetName()); }
 #endif
 
@@ -623,6 +627,8 @@ class CEntryStub : public CodeStub {
   Major MajorKey() { return CEntry; }
   int MinorKey();
 
+  bool NeedsImmovableCode();
+
   const char* GetName() { return "CEntryStub"; }
 };
 
index 96c757a..9e5692c 100644 (file)
@@ -605,8 +605,9 @@ Handle<JSFunction> Factory::NewFunctionWithoutPrototype(Handle<String> name,
 
 Handle<Code> Factory::NewCode(const CodeDesc& desc,
                               Code::Flags flags,
-                              Handle<Object> self_ref) {
-  CALL_HEAP_FUNCTION(Heap::CreateCode(desc, flags, self_ref), Code);
+                              Handle<Object> self_ref,
+                              bool immovable) {
+  CALL_HEAP_FUNCTION(Heap::CreateCode(desc, flags, self_ref, immovable), Code);
 }
 
 
index 7547f7c..ed16d77 100644 (file)
@@ -252,7 +252,8 @@ class Factory : public AllStatic {
 
   static Handle<Code> NewCode(const CodeDesc& desc,
                               Code::Flags flags,
-                              Handle<Object> self_reference);
+                              Handle<Object> self_reference,
+                              bool immovable = false);
 
   static Handle<Code> CopyCode(Handle<Code> code);
 
index 34ab9aa..55a31dc 100644 (file)
@@ -1906,20 +1906,6 @@ bool Heap::CreateApiObjects() {
 }
 
 
-void Heap::CreateCEntryStub() {
-  CEntryStub stub(1);
-  set_c_entry_code(*stub.GetCode());
-}
-
-
-#if V8_TARGET_ARCH_ARM && !V8_INTERPRETED_REGEXP
-void Heap::CreateRegExpCEntryStub() {
-  RegExpCEntryStub stub;
-  set_re_c_entry_code(*stub.GetCode());
-}
-#endif
-
-
 void Heap::CreateJSEntryStub() {
   JSEntryStub stub;
   set_js_entry_code(*stub.GetCode());
@@ -1932,14 +1918,6 @@ void Heap::CreateJSConstructEntryStub() {
 }
 
 
-#if V8_TARGET_ARCH_ARM
-void Heap::CreateDirectCEntryStub() {
-  DirectCEntryStub stub;
-  set_direct_c_entry_code(*stub.GetCode());
-}
-#endif
-
-
 void Heap::CreateFixedStubs() {
   // Here we create roots for fixed stubs. They are needed at GC
   // for cooking and uncooking (check out frames.cc).
@@ -1947,22 +1925,15 @@ void Heap::CreateFixedStubs() {
   // stub cache for these stubs.
   HandleScope scope;
   // gcc-4.4 has problem generating correct code of following snippet:
-  // {  CEntryStub stub;
-  //    c_entry_code_ = *stub.GetCode();
+  // {  JSEntryStub stub;
+  //    js_entry_code_ = *stub.GetCode();
   // }
-  // {  DebuggerStatementStub stub;
-  //    debugger_statement_code_ = *stub.GetCode();
+  // {  JSConstructEntryStub stub;
+  //    js_construct_entry_code_ = *stub.GetCode();
   // }
   // To workaround the problem, make separate functions without inlining.
-  Heap::CreateCEntryStub();
   Heap::CreateJSEntryStub();
   Heap::CreateJSConstructEntryStub();
-#if V8_TARGET_ARCH_ARM && !V8_INTERPRETED_REGEXP
-  Heap::CreateRegExpCEntryStub();
-#endif
-#if V8_TARGET_ARCH_ARM
-  Heap::CreateDirectCEntryStub();
-#endif
 }
 
 
@@ -2733,7 +2704,8 @@ MaybeObject* Heap::AllocateExternalArray(int length,
 
 MaybeObject* Heap::CreateCode(const CodeDesc& desc,
                               Code::Flags flags,
-                              Handle<Object> self_reference) {
+                              Handle<Object> self_reference,
+                              bool immovable) {
   // Allocate ByteArray before the Code object, so that we do not risk
   // leaving uninitialized Code object (and breaking the heap).
   Object* reloc_info;
@@ -2741,12 +2713,14 @@ MaybeObject* Heap::CreateCode(const CodeDesc& desc,
     if (!maybe_reloc_info->ToObject(&reloc_info)) return maybe_reloc_info;
   }
 
-  // Compute size
+  // Compute size.
   int body_size = RoundUp(desc.instr_size, kObjectAlignment);
   int obj_size = Code::SizeFor(body_size);
   ASSERT(IsAligned(static_cast<intptr_t>(obj_size), kCodeAlignment));
   MaybeObject* maybe_result;
-  if (obj_size > MaxObjectSizeInPagedSpace()) {
+  // Large code objects and code objects which should stay at a fixed address
+  // are allocated in large object space.
+  if (obj_size > MaxObjectSizeInPagedSpace() || immovable) {
     maybe_result = lo_space_->AllocateRawCode(obj_size);
   } else {
     maybe_result = code_space_->AllocateRaw(obj_size);
index 6aa8339..f95b1bb 100644 (file)
@@ -41,7 +41,7 @@ namespace internal {
 
 
 // Defines all the roots in Heap.
-#define UNCONDITIONAL_STRONG_ROOT_LIST(V)                                      \
+#define STRONG_ROOT_LIST(V)                                      \
   /* Put the byte array map early.  We need it to be in place by the time   */ \
   /* the deserializer hits the next page, since it wants to put a byte      */ \
   /* array in the unused space at the end of the page.                      */ \
@@ -114,26 +114,12 @@ namespace internal {
   V(NumberDictionary, non_monomorphic_cache, NonMonomorphicCache)              \
   V(Code, js_entry_code, JsEntryCode)                                          \
   V(Code, js_construct_entry_code, JsConstructEntryCode)                       \
-  V(Code, c_entry_code, CEntryCode)                                            \
   V(FixedArray, natives_source_cache, NativesSourceCache)                      \
   V(Object, last_script_id, LastScriptId)                                      \
   V(Script, empty_script, EmptyScript)                                         \
   V(Smi, real_stack_limit, RealStackLimit)                                     \
   V(StringDictionary, intrinsic_function_names, IntrinsicFunctionNames)        \
 
-#if V8_TARGET_ARCH_ARM && !V8_INTERPRETED_REGEXP
-#define STRONG_ROOT_LIST(V)                                                    \
-  UNCONDITIONAL_STRONG_ROOT_LIST(V)                                            \
-  V(Code, re_c_entry_code, RegExpCEntryCode)                                   \
-  V(Code, direct_c_entry_code, DirectCEntryCode)
-#elif V8_TARGET_ARCH_ARM
-#define STRONG_ROOT_LIST(V)                                                    \
-  UNCONDITIONAL_STRONG_ROOT_LIST(V)                                            \
-  V(Code, direct_c_entry_code, DirectCEntryCode)
-#else
-#define STRONG_ROOT_LIST(V) UNCONDITIONAL_STRONG_ROOT_LIST(V)
-#endif
-
 #define ROOT_LIST(V)                                  \
   STRONG_ROOT_LIST(V)                                 \
   V(SymbolTable, symbol_table, SymbolTable)
@@ -705,7 +691,8 @@ class Heap : public AllStatic {
   // Please note this function does not perform a garbage collection.
   MUST_USE_RESULT static MaybeObject* CreateCode(const CodeDesc& desc,
                                                  Code::Flags flags,
-                                                 Handle<Object> self_reference);
+                                                 Handle<Object> self_reference,
+                                                 bool immovable = false);
 
   MUST_USE_RESULT static MaybeObject* CopyCode(Code* code);
 
@@ -1327,13 +1314,10 @@ class Heap : public AllStatic {
   static bool CreateInitialMaps();
   static bool CreateInitialObjects();
 
-  // These five Create*EntryStub functions are here and forced to not be inlined
+  // These two Create*EntryStub functions are here and forced to not be inlined
   // because of a gcc-4.4 bug that assigns wrong vtable entries.
-  NO_INLINE(static void CreateCEntryStub());
   NO_INLINE(static void CreateJSEntryStub());
   NO_INLINE(static void CreateJSConstructEntryStub());
-  NO_INLINE(static void CreateRegExpCEntryStub());
-  NO_INLINE(static void CreateDirectCEntryStub());
 
   static void CreateFixedStubs();
 
index 7efa934..347f26b 100644 (file)
@@ -4647,6 +4647,11 @@ void CallFunctionStub::Generate(MacroAssembler* masm) {
 }
 
 
+bool CEntryStub::NeedsImmovableCode() {
+  return false;
+}
+
+
 void CEntryStub::GenerateThrowTOS(MacroAssembler* masm) {
   __ Throw(eax);
 }
index 0c7e962..b4f07ae 100644 (file)
@@ -3299,6 +3299,11 @@ void CallFunctionStub::Generate(MacroAssembler* masm) {
 }
 
 
+bool CEntryStub::NeedsImmovableCode() {
+  return false;
+}
+
+
 void CEntryStub::GenerateThrowTOS(MacroAssembler* masm) {
   // Throw exception in eax.
   __ Throw(rax);