| 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)
|
|
|