Index: src/builtins.cc |
diff --git a/src/builtins.cc b/src/builtins.cc |
index 97fcaebff5875553bc19e1aa33cd54bf3a61beea..b05ec6e517635684501e102d73d2d99ec83d2f86 100644 |
--- a/src/builtins.cc |
+++ b/src/builtins.cc |
@@ -1772,6 +1772,7 @@ struct BuiltinDesc { |
int name; |
Code::Flags flags; |
BuiltinExtraArguments extra_args; |
+ bool in_snapshot; // whether this builtin should be included in snapshot. |
}; |
#define BUILTIN_FUNCTION_TABLE_INIT { V8_ONCE_INIT, {} } |
@@ -1804,6 +1805,7 @@ void Builtins::InitBuiltinFunctionTable() { |
functions[builtin_count].name = builtin_count; |
functions[builtin_count].flags = static_cast<Code::Flags>(0); |
functions[builtin_count].extra_args = NO_EXTRA_ARGUMENTS; |
+ functions[builtin_count].in_snapshot = false; |
#define DEF_FUNCTION_PTR_C(aname, aextra_args) \ |
functions->generator = FUNCTION_ADDR(Generate_Adaptor); \ |
@@ -1812,9 +1814,10 @@ void Builtins::InitBuiltinFunctionTable() { |
functions->name = c_##aname; \ |
functions->flags = Code::ComputeFlags(Code::BUILTIN); \ |
functions->extra_args = aextra_args; \ |
+ functions->in_snapshot = true; \ |
++functions; |
-#define DEF_FUNCTION_PTR_A(aname, kind, state, extra) \ |
+#define DEF_FUNCTION_PTR_A(aname, kind, state, extra, in_snapshot_arg) \ |
functions->generator = FUNCTION_ADDR(Generate_##aname); \ |
functions->c_code = NULL; \ |
functions->s_name = #aname; \ |
@@ -1823,6 +1826,7 @@ void Builtins::InitBuiltinFunctionTable() { |
state, \ |
extra); \ |
functions->extra_args = NO_EXTRA_ARGUMENTS; \ |
+ functions->in_snapshot = (in_snapshot_arg == IN_SNAPSHOT); \ |
++functions; |
BUILTIN_LIST_C(DEF_FUNCTION_PTR_C) |
@@ -1833,8 +1837,8 @@ void Builtins::InitBuiltinFunctionTable() { |
#undef DEF_FUNCTION_PTR_A |
} |
-void Builtins::SetUp(bool create_heap_objects) { |
- ASSERT(!initialized_); |
+void Builtins::SetUp(SetUpKind set_up_kind) { |
+ ASSERT(!initialized_ || set_up_kind == AFTER_DESERIALIZATION); |
Isolate* isolate = Isolate::Current(); |
Heap* heap = isolate->heap(); |
@@ -1851,52 +1855,66 @@ void Builtins::SetUp(bool create_heap_objects) { |
// Traverse the list of builtins and generate an adaptor in a |
// separate code object for each one. |
for (int i = 0; i < builtin_count; i++) { |
- if (create_heap_objects) { |
- MacroAssembler masm(isolate, u.buffer, sizeof u.buffer); |
- // Generate the code/adaptor. |
- typedef void (*Generator)(MacroAssembler*, int, BuiltinExtraArguments); |
- Generator g = FUNCTION_CAST<Generator>(functions[i].generator); |
- // We pass all arguments to the generator, but it may not use all of |
- // them. This works because the first arguments are on top of the |
- // stack. |
- ASSERT(!masm.has_frame()); |
- g(&masm, functions[i].name, functions[i].extra_args); |
- // Move the code into the object heap. |
- CodeDesc desc; |
- masm.GetCode(&desc); |
- Code::Flags flags = functions[i].flags; |
- Object* code = NULL; |
- { |
- // During startup it's OK to always allocate and defer GC to later. |
- // This simplifies things because we don't need to retry. |
- AlwaysAllocateScope __scope__; |
- { MaybeObject* maybe_code = |
- heap->CreateCode(desc, flags, masm.CodeObject()); |
- if (!maybe_code->ToObject(&code)) { |
- v8::internal::V8::FatalProcessOutOfMemory("CreateCode"); |
- } |
+ if (set_up_kind == AFTER_DESERIALIZATION && functions[i].in_snapshot) { |
+ // This builtin was deserialized from the snapshot. |
+ ASSERT(builtins_[i] != NULL); |
+ continue; |
+ } |
+ |
+ if (set_up_kind == FOR_SNAPSHOT && !functions[i].in_snapshot) { |
+ // This builtin should not be included in the snapshot. |
+ builtins_[i] = NULL; |
+ continue; |
+ } |
+ |
+ names_[i] = functions[i].s_name; |
+ |
+ if (set_up_kind == BEFORE_DESERIALIZATION) { |
+ builtins_[i] = NULL; |
+ continue; |
+ } |
+ |
+ MacroAssembler masm(isolate, u.buffer, sizeof u.buffer); |
+ // Generate the code/adaptor. |
+ typedef void (*Generator)(MacroAssembler*, int, BuiltinExtraArguments); |
+ Generator g = FUNCTION_CAST<Generator>(functions[i].generator); |
+ // We pass all arguments to the generator, but it may not use all of |
+ // them. This works because the first arguments are on top of the |
+ // stack. |
+ ASSERT(!masm.has_frame()); |
+ g(&masm, functions[i].name, functions[i].extra_args); |
+ // Move the code into the object heap. |
+ CodeDesc desc; |
+ masm.GetCode(&desc); |
+ Code::Flags flags = functions[i].flags; |
+ Object* code = NULL; |
+ { |
+ // During startup it's OK to always allocate and defer GC to later. |
+ // This simplifies things because we don't need to retry. |
+ AlwaysAllocateScope __scope__; |
+ { MaybeObject* maybe_code = |
+ heap->CreateCode(desc, flags, masm.CodeObject()); |
+ if (!maybe_code->ToObject(&code)) { |
+ v8::internal::V8::FatalProcessOutOfMemory("CreateCode"); |
} |
} |
- // Log the event and add the code to the builtins array. |
- PROFILE(isolate, |
- CodeCreateEvent(Logger::BUILTIN_TAG, |
- Code::cast(code), |
- functions[i].s_name)); |
- GDBJIT(AddCode(GDBJITInterface::BUILTIN, |
- functions[i].s_name, |
- Code::cast(code))); |
- builtins_[i] = code; |
+ } |
+ // Log the event and add the code to the builtins array. |
+ PROFILE(isolate, |
+ CodeCreateEvent(Logger::BUILTIN_TAG, |
+ Code::cast(code), |
+ functions[i].s_name)); |
+ GDBJIT(AddCode(GDBJITInterface::BUILTIN, |
+ functions[i].s_name, |
+ Code::cast(code))); |
+ builtins_[i] = code; |
#ifdef ENABLE_DISASSEMBLER |
- if (FLAG_print_builtin_code) { |
- PrintF("Builtin: %s\n", functions[i].s_name); |
- Code::cast(code)->Disassemble(functions[i].s_name); |
- PrintF("\n"); |
- } |
-#endif |
- } else { |
- // Deserializing. The values will be filled in during IterateBuiltins. |
- builtins_[i] = NULL; |
+ if (FLAG_print_builtin_code) { |
+ PrintF("Builtin: %s\n", functions[i].s_name); |
+ Code::cast(code)->Disassemble(functions[i].s_name); |
+ PrintF("\n"); |
} |
+#endif |
names_[i] = functions[i].s_name; |
} |
@@ -1935,11 +1953,11 @@ Handle<Code> Builtins::name() { \ |
reinterpret_cast<Code**>(builtin_address(k##name)); \ |
return Handle<Code>(code_address); \ |
} |
-#define DEFINE_BUILTIN_ACCESSOR_A(name, kind, state, extra) \ |
-Handle<Code> Builtins::name() { \ |
- Code** code_address = \ |
- reinterpret_cast<Code**>(builtin_address(k##name)); \ |
- return Handle<Code>(code_address); \ |
+#define DEFINE_BUILTIN_ACCESSOR_A(name, kind, state, extra, extra2) \ |
+Handle<Code> Builtins::name() { \ |
+ Code** code_address = \ |
+ reinterpret_cast<Code**>(builtin_address(k##name)); \ |
+ return Handle<Code>(code_address); \ |
} |
BUILTIN_LIST_C(DEFINE_BUILTIN_ACCESSOR_C) |
BUILTIN_LIST_A(DEFINE_BUILTIN_ACCESSOR_A) |