Index: src/bootstrapper.cc |
diff --git a/src/bootstrapper.cc b/src/bootstrapper.cc |
index e0e6f6dd85f7ad006a55335bbe9bc650f9962825..2362fa402aab2d646a403158f5caeae18b2bd0d0 100644 |
--- a/src/bootstrapper.cc |
+++ b/src/bootstrapper.cc |
@@ -204,6 +204,9 @@ class Genesis BASE_EMBEDDED { |
// Used for creating a context from scratch. |
void InstallNativeFunctions(); |
void InstallExperimentalNativeFunctions(); |
+ Handle<JSFunction> InstallInternalArray(Handle<JSBuiltinsObject> builtins, |
+ const char* name, |
+ ElementsKind elements_kind); |
bool InstallNatives(); |
bool InstallExperimentalNatives(); |
void InstallBuiltinFunctionIds(); |
@@ -1440,6 +1443,60 @@ void Genesis::InstallExperimentalNativeFunctions() { |
#undef INSTALL_NATIVE |
+Handle<JSFunction> Genesis::InstallInternalArray( |
+ Handle<JSBuiltinsObject> builtins, |
+ const char* name, |
+ ElementsKind elements_kind) { |
+ // --- I n t e r n a l A r r a y --- |
+ // An array constructor on the builtins object that works like |
+ // the public Array constructor, except that its prototype |
+ // doesn't inherit from Object.prototype. |
+ // To be used only for internal work by builtins. Instances |
+ // must not be leaked to user code. |
+ Handle<JSFunction> array_function = |
+ InstallFunction(builtins, |
+ name, |
+ JS_ARRAY_TYPE, |
+ JSArray::kSize, |
+ isolate()->initial_object_prototype(), |
+ Builtins::kInternalArrayCode, |
+ true); |
+ Handle<JSObject> prototype = |
+ factory()->NewJSObject(isolate()->object_function(), TENURED); |
+ SetPrototype(array_function, prototype); |
+ |
+ array_function->shared()->set_construct_stub( |
+ isolate()->builtins()->builtin(Builtins::kArrayConstructCode)); |
+ array_function->shared()->DontAdaptArguments(); |
+ |
+ MaybeObject* maybe_map = array_function->initial_map()->Copy(); |
+ Map* new_map; |
+ if (!maybe_map->To(&new_map)) return Handle<JSFunction>::null(); |
+ new_map->set_elements_kind(elements_kind); |
+ array_function->set_initial_map(new_map); |
+ |
+ // Make "length" magic on instances. |
+ Handle<Map> initial_map(array_function->initial_map()); |
+ Handle<DescriptorArray> array_descriptors( |
+ factory()->NewDescriptorArray(0, 1)); |
+ DescriptorArray::WhitenessWitness witness(*array_descriptors); |
+ |
+ Handle<Foreign> array_length(factory()->NewForeign( |
+ &Accessors::ArrayLength)); |
+ PropertyAttributes attribs = static_cast<PropertyAttributes>( |
+ DONT_ENUM | DONT_DELETE); |
+ initial_map->set_instance_descriptors(*array_descriptors); |
+ |
+ { // Add length. |
+ CallbacksDescriptor d( |
+ *factory()->length_symbol(), *array_length, attribs); |
+ array_function->initial_map()->AppendDescriptor(&d, witness); |
+ } |
+ |
+ return array_function; |
+} |
+ |
+ |
bool Genesis::InstallNatives() { |
HandleScope scope(isolate()); |
@@ -1662,60 +1719,25 @@ bool Genesis::InstallNatives() { |
native_context()->set_opaque_reference_function(*opaque_reference_fun); |
} |
- { // --- I n t e r n a l A r r a y --- |
- // An array constructor on the builtins object that works like |
- // the public Array constructor, except that its prototype |
- // doesn't inherit from Object.prototype. |
- // To be used only for internal work by builtins. Instances |
- // must not be leaked to user code. |
- Handle<JSFunction> array_function = |
- InstallFunction(builtins, |
- "InternalArray", |
- JS_ARRAY_TYPE, |
- JSArray::kSize, |
- isolate()->initial_object_prototype(), |
- Builtins::kInternalArrayCode, |
- true); |
- Handle<JSObject> prototype = |
- factory()->NewJSObject(isolate()->object_function(), TENURED); |
- SetPrototype(array_function, prototype); |
- |
- array_function->shared()->set_construct_stub( |
- isolate()->builtins()->builtin(Builtins::kArrayConstructCode)); |
- array_function->shared()->DontAdaptArguments(); |
- |
- // InternalArrays should not use Smi-Only array optimizations. There are too |
- // many places in the C++ runtime code (e.g. RegEx) that assume that |
- // elements in InternalArrays can be set to non-Smi values without going |
- // through a common bottleneck that would make the SMI_ONLY -> FAST_ELEMENT |
- // transition easy to trap. Moreover, they rarely are smi-only. |
- MaybeObject* maybe_map = array_function->initial_map()->Copy(); |
- Map* new_map; |
- if (!maybe_map->To(&new_map)) return false; |
- new_map->set_elements_kind(FAST_HOLEY_ELEMENTS); |
- array_function->set_initial_map(new_map); |
- |
- // Make "length" magic on instances. |
- Handle<Map> initial_map(array_function->initial_map()); |
- Handle<DescriptorArray> array_descriptors( |
- factory()->NewDescriptorArray(0, 1)); |
- DescriptorArray::WhitenessWitness witness(*array_descriptors); |
- |
- Handle<Foreign> array_length(factory()->NewForeign( |
- &Accessors::ArrayLength)); |
- PropertyAttributes attribs = static_cast<PropertyAttributes>( |
- DONT_ENUM | DONT_DELETE); |
- initial_map->set_instance_descriptors(*array_descriptors); |
- |
- { // Add length. |
- CallbacksDescriptor d( |
- *factory()->length_symbol(), *array_length, attribs); |
- array_function->initial_map()->AppendDescriptor(&d, witness); |
- } |
+ // InternalArrays should not use Smi-Only array optimizations. There are too |
+ // many places in the C++ runtime code (e.g. RegEx) that assume that |
+ // elements in InternalArrays can be set to non-Smi values without going |
+ // through a common bottleneck that would make the SMI_ONLY -> FAST_ELEMENT |
+ // transition easy to trap. Moreover, they rarely are smi-only. |
+ { |
+ Handle<JSFunction> array_function = |
+ InstallInternalArray(builtins, "InternalArray", FAST_HOLEY_ELEMENTS); |
+ if (array_function.is_null()) return false; |
native_context()->set_internal_array_function(*array_function); |
} |
+ { |
+ Handle<JSFunction> array_function = |
+ InstallInternalArray(builtins, "InternalPackedArray", FAST_ELEMENTS); |
+ if (array_function.is_null()) return false; |
+ } |
+ |
if (FLAG_disable_native_files) { |
PrintF("Warning: Running without installed natives!\n"); |
return true; |
@@ -1789,7 +1811,9 @@ bool Genesis::InstallNatives() { |
// Add initial map. |
Handle<Map> initial_map = |
- factory()->NewMap(JS_ARRAY_TYPE, JSRegExpResult::kSize); |
+ factory()->NewMap(JS_ARRAY_TYPE, |
+ JSRegExpResult::kSize, |
+ FAST_ELEMENTS); |
initial_map->set_constructor(*array_constructor); |
// Set prototype on map. |