Index: src/bootstrapper.cc |
diff --git a/src/bootstrapper.cc b/src/bootstrapper.cc |
index 12efbc17ab1dce65edb519496bda9dcbc953a9e6..1bbfcb72d7647310babd59942eb19c9a8c247324 100644 |
--- a/src/bootstrapper.cc |
+++ b/src/bootstrapper.cc |
@@ -245,11 +245,14 @@ class Genesis BASE_EMBEDDED { |
bool make_prototype_enumerable = false); |
void MakeFunctionInstancePrototypeWritable(); |
- void AddSpecialFunction(Handle<JSObject> prototype, |
- const char* name, |
- Handle<Code> code); |
+ Handle<JSFunction> MakeFunctionForBuiltin(Handle<String> name, |
+ Handle<Code> code); |
- void BuildSpecialFunctionTable(); |
+ void OverrideWithSpecialFunction(Handle<JSObject> prototype, |
+ const char* name, |
+ Handle<Code> code); |
+ |
+ void InstallSpecialFunctions(); |
static bool CompileBuiltin(int index); |
static bool CompileNative(Vector<const char> name, Handle<String> source); |
@@ -777,8 +780,6 @@ void Genesis::CreateRoots(v8::Handle<v8::ObjectTemplate> global_template, |
delegate->shared()->DontAdaptArguments(); |
} |
- global_context()->set_special_function_table(Heap::empty_fixed_array()); |
- |
// Initialize the out of memory slot. |
global_context()->set_out_of_memory(Heap::false_value()); |
@@ -1457,33 +1458,35 @@ void Genesis::MakeFunctionInstancePrototypeWritable() { |
} |
-void Genesis::AddSpecialFunction(Handle<JSObject> prototype, |
- const char* name, |
- Handle<Code> code) { |
+Handle<JSFunction> Genesis::MakeFunctionForBuiltin(Handle<String> name, |
+ Handle<Code> code) { |
+ Handle<JSFunction> optimized = Factory::NewFunction(name, |
+ JS_OBJECT_TYPE, |
+ JSObject::kHeaderSize, |
+ code, |
+ false); |
+ optimized->shared()->DontAdaptArguments(); |
+ return optimized; |
+} |
+ |
+ |
+void Genesis::OverrideWithSpecialFunction(Handle<JSObject> prototype, |
+ const char* name, |
+ Handle<Code> code) { |
Handle<String> key = Factory::LookupAsciiSymbol(name); |
- Handle<Object> value = Handle<Object>(prototype->GetProperty(*key)); |
- if (value->IsJSFunction()) { |
- Handle<JSFunction> optimized = Factory::NewFunction(key, |
- JS_OBJECT_TYPE, |
- JSObject::kHeaderSize, |
- code, |
- false); |
- optimized->shared()->DontAdaptArguments(); |
- int len = global_context()->special_function_table()->length(); |
- Handle<FixedArray> new_array = Factory::NewFixedArray(len + 3); |
- for (int index = 0; index < len; index++) { |
- new_array->set(index, |
- global_context()->special_function_table()->get(index)); |
- } |
- new_array->set(len+0, *prototype); |
- new_array->set(len+1, *value); |
- new_array->set(len+2, *optimized); |
- global_context()->set_special_function_table(*new_array); |
- } |
+ Handle<Object> old_value = GetProperty(prototype, key); |
+ // Check if the function is present in the first place. |
+ // For example, FLAG_natives_file could affect if Array functions |
+ // are installed at all. |
+ if (!old_value->IsJSFunction()) return; |
+ int old_length = Handle<JSFunction>::cast(old_value)->shared()->length(); |
+ Handle<JSFunction> optimized = MakeFunctionForBuiltin(key, code); |
+ optimized->shared()->set_length(old_length); |
+ SetProperty(prototype, key, optimized, NONE); |
} |
-void Genesis::BuildSpecialFunctionTable() { |
+void Genesis::InstallSpecialFunctions() { |
HandleScope scope; |
Handle<JSObject> global = Handle<JSObject>(global_context()->global()); |
// Add special versions for some Array.prototype functions. |
@@ -1501,18 +1504,24 @@ void Genesis::BuildSpecialFunctionTable() { |
} else { |
special_prototype = visible_prototype; |
} |
- AddSpecialFunction(special_prototype, "pop", |
- Handle<Code>(Builtins::builtin(Builtins::ArrayPop))); |
- AddSpecialFunction(special_prototype, "push", |
- Handle<Code>(Builtins::builtin(Builtins::ArrayPush))); |
- AddSpecialFunction(special_prototype, "shift", |
- Handle<Code>(Builtins::builtin(Builtins::ArrayShift))); |
- AddSpecialFunction(special_prototype, "unshift", |
- Handle<Code>(Builtins::builtin(Builtins::ArrayUnshift))); |
- AddSpecialFunction(special_prototype, "slice", |
- Handle<Code>(Builtins::builtin(Builtins::ArraySlice))); |
- AddSpecialFunction(special_prototype, "splice", |
- Handle<Code>(Builtins::builtin(Builtins::ArraySplice))); |
+ OverrideWithSpecialFunction( |
+ special_prototype, "pop", |
+ Handle<Code>(Builtins::builtin(Builtins::ArrayPop))); |
+ OverrideWithSpecialFunction( |
+ special_prototype, "push", |
+ Handle<Code>(Builtins::builtin(Builtins::ArrayPush))); |
+ OverrideWithSpecialFunction( |
+ special_prototype, "shift", |
+ Handle<Code>(Builtins::builtin(Builtins::ArrayShift))); |
+ OverrideWithSpecialFunction( |
+ special_prototype, "unshift", |
+ Handle<Code>(Builtins::builtin(Builtins::ArrayUnshift))); |
+ OverrideWithSpecialFunction( |
+ special_prototype, "slice", |
+ Handle<Code>(Builtins::builtin(Builtins::ArraySlice))); |
+ OverrideWithSpecialFunction( |
+ special_prototype, "splice", |
+ Handle<Code>(Builtins::builtin(Builtins::ArraySplice))); |
} |
@@ -1539,7 +1548,7 @@ Genesis::Genesis(Handle<Object> global_object, |
if (!InstallNatives()) return; |
MakeFunctionInstancePrototypeWritable(); |
- BuildSpecialFunctionTable(); |
+ InstallSpecialFunctions(); |
if (!ConfigureGlobalObjects(global_template)) return; |