Commit 061fa8be authored by sgjesse@chromium.org's avatar sgjesse@chromium.org

Add the possibility for a code stub to be non-movable

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
parent df7bbc23
...@@ -4156,6 +4156,11 @@ void MathPowStub::Generate(MacroAssembler* masm) { ...@@ -4156,6 +4156,11 @@ void MathPowStub::Generate(MacroAssembler* masm) {
} }
bool CEntryStub::NeedsImmovableCode() {
return true;
}
void CEntryStub::GenerateThrowTOS(MacroAssembler* masm) { void CEntryStub::GenerateThrowTOS(MacroAssembler* masm) {
__ Throw(r0); __ Throw(r0);
} }
......
...@@ -588,6 +588,9 @@ class RegExpCEntryStub: public CodeStub { ...@@ -588,6 +588,9 @@ class RegExpCEntryStub: public CodeStub {
private: private:
Major MajorKey() { return RegExpCEntry; } Major MajorKey() { return RegExpCEntry; }
int MinorKey() { return 0; } int MinorKey() { return 0; }
bool NeedsImmovableCode() { return true; }
const char* GetName() { return "RegExpCEntryStub"; } const char* GetName() { return "RegExpCEntryStub"; }
}; };
...@@ -607,6 +610,9 @@ class DirectCEntryStub: public CodeStub { ...@@ -607,6 +610,9 @@ class DirectCEntryStub: public CodeStub {
private: private:
Major MajorKey() { return DirectCEntry; } Major MajorKey() { return DirectCEntry; }
int MinorKey() { return 0; } int MinorKey() { return 0; }
bool NeedsImmovableCode() { return true; }
const char* GetName() { return "DirectCEntryStub"; } const char* GetName() { return "DirectCEntryStub"; }
}; };
......
...@@ -101,7 +101,8 @@ Handle<Code> CodeStub::GetCode() { ...@@ -101,7 +101,8 @@ Handle<Code> CodeStub::GetCode() {
static_cast<Code::Kind>(GetCodeKind()), static_cast<Code::Kind>(GetCodeKind()),
InLoop(), InLoop(),
GetICState()); 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); RecordCodeGeneration(*new_object, &masm);
FinishCode(*new_object); FinishCode(*new_object);
...@@ -116,6 +117,7 @@ Handle<Code> CodeStub::GetCode() { ...@@ -116,6 +117,7 @@ Handle<Code> CodeStub::GetCode() {
code = *new_object; code = *new_object;
} }
ASSERT(!NeedsImmovableCode() || Heap::lo_space()->Contains(code));
return Handle<Code>(code); return Handle<Code>(code);
} }
......
...@@ -167,7 +167,11 @@ class CodeStub BASE_EMBEDDED { ...@@ -167,7 +167,11 @@ class CodeStub BASE_EMBEDDED {
// Returns a name for logging/debugging purposes. // Returns a name for logging/debugging purposes.
virtual const char* GetName() { return MajorName(MajorKey(), false); } 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()); } virtual void Print() { PrintF("%s\n", GetName()); }
#endif #endif
...@@ -623,6 +627,8 @@ class CEntryStub : public CodeStub { ...@@ -623,6 +627,8 @@ class CEntryStub : public CodeStub {
Major MajorKey() { return CEntry; } Major MajorKey() { return CEntry; }
int MinorKey(); int MinorKey();
bool NeedsImmovableCode();
const char* GetName() { return "CEntryStub"; } const char* GetName() { return "CEntryStub"; }
}; };
......
...@@ -605,8 +605,9 @@ Handle<JSFunction> Factory::NewFunctionWithoutPrototype(Handle<String> name, ...@@ -605,8 +605,9 @@ Handle<JSFunction> Factory::NewFunctionWithoutPrototype(Handle<String> name,
Handle<Code> Factory::NewCode(const CodeDesc& desc, Handle<Code> Factory::NewCode(const CodeDesc& desc,
Code::Flags flags, Code::Flags flags,
Handle<Object> self_ref) { Handle<Object> self_ref,
CALL_HEAP_FUNCTION(Heap::CreateCode(desc, flags, self_ref), Code); bool immovable) {
CALL_HEAP_FUNCTION(Heap::CreateCode(desc, flags, self_ref, immovable), Code);
} }
......
...@@ -252,7 +252,8 @@ class Factory : public AllStatic { ...@@ -252,7 +252,8 @@ class Factory : public AllStatic {
static Handle<Code> NewCode(const CodeDesc& desc, static Handle<Code> NewCode(const CodeDesc& desc,
Code::Flags flags, Code::Flags flags,
Handle<Object> self_reference); Handle<Object> self_reference,
bool immovable = false);
static Handle<Code> CopyCode(Handle<Code> code); static Handle<Code> CopyCode(Handle<Code> code);
......
...@@ -1906,20 +1906,6 @@ bool Heap::CreateApiObjects() { ...@@ -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() { void Heap::CreateJSEntryStub() {
JSEntryStub stub; JSEntryStub stub;
set_js_entry_code(*stub.GetCode()); set_js_entry_code(*stub.GetCode());
...@@ -1932,14 +1918,6 @@ void Heap::CreateJSConstructEntryStub() { ...@@ -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() { void Heap::CreateFixedStubs() {
// Here we create roots for fixed stubs. They are needed at GC // Here we create roots for fixed stubs. They are needed at GC
// for cooking and uncooking (check out frames.cc). // for cooking and uncooking (check out frames.cc).
...@@ -1947,22 +1925,15 @@ void Heap::CreateFixedStubs() { ...@@ -1947,22 +1925,15 @@ void Heap::CreateFixedStubs() {
// stub cache for these stubs. // stub cache for these stubs.
HandleScope scope; HandleScope scope;
// gcc-4.4 has problem generating correct code of following snippet: // gcc-4.4 has problem generating correct code of following snippet:
// { CEntryStub stub; // { JSEntryStub stub;
// c_entry_code_ = *stub.GetCode(); // js_entry_code_ = *stub.GetCode();
// } // }
// { DebuggerStatementStub stub; // { JSConstructEntryStub stub;
// debugger_statement_code_ = *stub.GetCode(); // js_construct_entry_code_ = *stub.GetCode();
// } // }
// To workaround the problem, make separate functions without inlining. // To workaround the problem, make separate functions without inlining.
Heap::CreateCEntryStub();
Heap::CreateJSEntryStub(); Heap::CreateJSEntryStub();
Heap::CreateJSConstructEntryStub(); 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, ...@@ -2733,7 +2704,8 @@ MaybeObject* Heap::AllocateExternalArray(int length,
MaybeObject* Heap::CreateCode(const CodeDesc& desc, MaybeObject* Heap::CreateCode(const CodeDesc& desc,
Code::Flags flags, 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 // Allocate ByteArray before the Code object, so that we do not risk
// leaving uninitialized Code object (and breaking the heap). // leaving uninitialized Code object (and breaking the heap).
Object* reloc_info; Object* reloc_info;
...@@ -2741,12 +2713,14 @@ MaybeObject* Heap::CreateCode(const CodeDesc& desc, ...@@ -2741,12 +2713,14 @@ MaybeObject* Heap::CreateCode(const CodeDesc& desc,
if (!maybe_reloc_info->ToObject(&reloc_info)) return maybe_reloc_info; if (!maybe_reloc_info->ToObject(&reloc_info)) return maybe_reloc_info;
} }
// Compute size // Compute size.
int body_size = RoundUp(desc.instr_size, kObjectAlignment); int body_size = RoundUp(desc.instr_size, kObjectAlignment);
int obj_size = Code::SizeFor(body_size); int obj_size = Code::SizeFor(body_size);
ASSERT(IsAligned(static_cast<intptr_t>(obj_size), kCodeAlignment)); ASSERT(IsAligned(static_cast<intptr_t>(obj_size), kCodeAlignment));
MaybeObject* maybe_result; 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); maybe_result = lo_space_->AllocateRawCode(obj_size);
} else { } else {
maybe_result = code_space_->AllocateRaw(obj_size); maybe_result = code_space_->AllocateRaw(obj_size);
......
...@@ -41,7 +41,7 @@ namespace internal { ...@@ -41,7 +41,7 @@ namespace internal {
// Defines all the roots in Heap. // 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 */ \ /* 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 */ \ /* the deserializer hits the next page, since it wants to put a byte */ \
/* array in the unused space at the end of the page. */ \ /* array in the unused space at the end of the page. */ \
...@@ -114,26 +114,12 @@ namespace internal { ...@@ -114,26 +114,12 @@ namespace internal {
V(NumberDictionary, non_monomorphic_cache, NonMonomorphicCache) \ V(NumberDictionary, non_monomorphic_cache, NonMonomorphicCache) \
V(Code, js_entry_code, JsEntryCode) \ V(Code, js_entry_code, JsEntryCode) \
V(Code, js_construct_entry_code, JsConstructEntryCode) \ V(Code, js_construct_entry_code, JsConstructEntryCode) \
V(Code, c_entry_code, CEntryCode) \
V(FixedArray, natives_source_cache, NativesSourceCache) \ V(FixedArray, natives_source_cache, NativesSourceCache) \
V(Object, last_script_id, LastScriptId) \ V(Object, last_script_id, LastScriptId) \
V(Script, empty_script, EmptyScript) \ V(Script, empty_script, EmptyScript) \
V(Smi, real_stack_limit, RealStackLimit) \ V(Smi, real_stack_limit, RealStackLimit) \
V(StringDictionary, intrinsic_function_names, IntrinsicFunctionNames) \ 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) \ #define ROOT_LIST(V) \
STRONG_ROOT_LIST(V) \ STRONG_ROOT_LIST(V) \
V(SymbolTable, symbol_table, SymbolTable) V(SymbolTable, symbol_table, SymbolTable)
...@@ -705,7 +691,8 @@ class Heap : public AllStatic { ...@@ -705,7 +691,8 @@ class Heap : public AllStatic {
// Please note this function does not perform a garbage collection. // Please note this function does not perform a garbage collection.
MUST_USE_RESULT static MaybeObject* CreateCode(const CodeDesc& desc, MUST_USE_RESULT static MaybeObject* CreateCode(const CodeDesc& desc,
Code::Flags flags, Code::Flags flags,
Handle<Object> self_reference); Handle<Object> self_reference,
bool immovable = false);
MUST_USE_RESULT static MaybeObject* CopyCode(Code* code); MUST_USE_RESULT static MaybeObject* CopyCode(Code* code);
...@@ -1327,13 +1314,10 @@ class Heap : public AllStatic { ...@@ -1327,13 +1314,10 @@ class Heap : public AllStatic {
static bool CreateInitialMaps(); static bool CreateInitialMaps();
static bool CreateInitialObjects(); 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. // 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 CreateJSEntryStub());
NO_INLINE(static void CreateJSConstructEntryStub()); NO_INLINE(static void CreateJSConstructEntryStub());
NO_INLINE(static void CreateRegExpCEntryStub());
NO_INLINE(static void CreateDirectCEntryStub());
static void CreateFixedStubs(); static void CreateFixedStubs();
......
...@@ -4647,6 +4647,11 @@ void CallFunctionStub::Generate(MacroAssembler* masm) { ...@@ -4647,6 +4647,11 @@ void CallFunctionStub::Generate(MacroAssembler* masm) {
} }
bool CEntryStub::NeedsImmovableCode() {
return false;
}
void CEntryStub::GenerateThrowTOS(MacroAssembler* masm) { void CEntryStub::GenerateThrowTOS(MacroAssembler* masm) {
__ Throw(eax); __ Throw(eax);
} }
......
...@@ -3299,6 +3299,11 @@ void CallFunctionStub::Generate(MacroAssembler* masm) { ...@@ -3299,6 +3299,11 @@ void CallFunctionStub::Generate(MacroAssembler* masm) {
} }
bool CEntryStub::NeedsImmovableCode() {
return false;
}
void CEntryStub::GenerateThrowTOS(MacroAssembler* masm) { void CEntryStub::GenerateThrowTOS(MacroAssembler* masm) {
// Throw exception in eax. // Throw exception in eax.
__ Throw(rax); __ Throw(rax);
......
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