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) {
}
bool CEntryStub::NeedsImmovableCode() {
return true;
}
void CEntryStub::GenerateThrowTOS(MacroAssembler* masm) {
__ Throw(r0);
}
......
......@@ -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"; }
};
......
......@@ -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);
}
......
......@@ -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"; }
};
......
......@@ -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);
}
......
......@@ -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);
......
......@@ -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);
......
......@@ -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();
......
......@@ -4647,6 +4647,11 @@ void CallFunctionStub::Generate(MacroAssembler* masm) {
}
bool CEntryStub::NeedsImmovableCode() {
return false;
}
void CEntryStub::GenerateThrowTOS(MacroAssembler* masm) {
__ Throw(eax);
}
......
......@@ -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);
......
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