Introduce InternalPackedArray.
authoryangguo@chromium.org <yangguo@chromium.org@ce2b1a6d-e550-0410-aec6-3dcde31c8c00>
Fri, 15 Feb 2013 15:20:05 +0000 (15:20 +0000)
committeryangguo@chromium.org <yangguo@chromium.org@ce2b1a6d-e550-0410-aec6-3dcde31c8c00>
Fri, 15 Feb 2013 15:20:05 +0000 (15:20 +0000)
R=jkummerow@chromium.org
BUG=

Review URL: https://chromiumcodereview.appspot.com/12255049

git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@13678 ce2b1a6d-e550-0410-aec6-3dcde31c8c00

src/array.js
src/bootstrapper.cc
src/json.js
src/messages.js
src/regexp.js
src/string.js
src/v8natives.js

index 47f796d..9b0bfe1 100644 (file)
@@ -1559,6 +1559,12 @@ function SetUpArray() {
     "push", getFunction("push", ArrayPush),
     "splice", getFunction("splice", ArraySplice)
   ));
+
+  SetUpLockedPrototype(InternalPackedArray, $Array(), $Array(
+    "join", getFunction("join", ArrayJoin),
+    "pop", getFunction("pop", ArrayPop),
+    "push", getFunction("push", ArrayPush)
+  ));
 }
 
 SetUpArray();
index e0e6f6d..2362fa4 100644 (file)
@@ -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.
index 9ab1a31..7818d9b 100644 (file)
@@ -67,7 +67,7 @@ function SerializeArray(value, replacer, stack, indent, gap) {
   }
   var stepback = indent;
   indent += gap;
-  var partial = new InternalArray();
+  var partial = new InternalPackedArray();
   var len = value.length;
   for (var i = 0; i < len; i++) {
     var strP = JSONSerialize($String(i), value, replacer, stack,
@@ -97,7 +97,7 @@ function SerializeObject(value, replacer, stack, indent, gap) {
   }
   var stepback = indent;
   indent += gap;
-  var partial = new InternalArray();
+  var partial = new InternalPackedArray();
   if (IS_ARRAY(replacer)) {
     var length = replacer.length;
     for (var i = 0; i < length; i++) {
index 4a8143e..0d9c90d 100644 (file)
@@ -557,7 +557,7 @@ function ScriptNameOrSourceURL() {
     // Don't reuse lastMatchInfo here, so we create a new array with room
     // for four captures (array with length one longer than the index
     // of the fourth capture, where the numbering is zero-based).
-    var matchInfo = new InternalArray(CAPTURE(3) + 1);
+    var matchInfo = new InternalPackedArray(CAPTURE(3) + 1);
     var match =
         %_RegExpExec(sourceUrlPattern, source, sourceUrlPos - 4, matchInfo);
     if (match) {
@@ -1033,7 +1033,7 @@ function FormatErrorString(error) {
 
 
 function GetStackFrames(raw_stack) {
-  var frames = new InternalArray();
+  var frames = new InternalPackedArray();
   for (var i = 0; i < raw_stack.length; i += 4) {
     var recv = raw_stack[i];
     var fun = raw_stack[i + 1];
@@ -1047,7 +1047,7 @@ function GetStackFrames(raw_stack) {
 
 
 function FormatStackTrace(error_string, frames) {
-  var lines = new InternalArray();
+  var lines = new InternalPackedArray();
   lines.push(error_string);
   for (var i = 0; i < frames.length; i++) {
     var frame = frames[i];
index da1883f..a8390b0 100644 (file)
@@ -385,7 +385,7 @@ function RegExpMakeCaptureGetter(n) {
 // pairs for the match and all the captured substrings), the invariant is
 // that there are at least two capture indeces.  The array also contains
 // the subject string for the last successful match.
-var lastMatchInfo = new InternalArray(
+var lastMatchInfo = new InternalPackedArray(
     2,                 // REGEXP_NUMBER_OF_CAPTURES
     "",                // Last subject.
     void 0,            // Last input - settable with RegExpSetInput.
index b39976c..2f7df70 100644 (file)
@@ -420,7 +420,7 @@ function StringReplaceGlobalRegExpWithFunction(subject, regexp, replace) {
     // input string and some replacements that were returned from the replace
     // function.
     var match_start = 0;
-    var override = new InternalArray(null, 0, subject);
+    var override = new InternalPackedArray(null, 0, subject);
     var receiver = %GetDefaultReceiver(replace);
     for (var i = 0; i < len; i++) {
       var elem = res[i];
@@ -821,8 +821,6 @@ function StringTrimRight() {
   return %StringTrim(TO_STRING_INLINE(this), false, true);
 }
 
-var static_charcode_array = new InternalArray(4);
-
 
 // ECMA-262, section 15.5.3.2
 function StringFromCharCode(code) {
index 3978e88..f92c949 100644 (file)
@@ -1117,7 +1117,7 @@ function ObjectDefineProperty(obj, p, attributes) {
 
 
 function GetOwnEnumerablePropertyNames(properties) {
-  var names = new InternalArray();
+  var names = new InternalPackedArray();
   for (var key in properties) {
     if (%HasLocalProperty(properties, key)) {
       names.push(key);
@@ -1134,7 +1134,7 @@ function ObjectDefineProperties(obj, properties) {
   }
   var props = ToObject(properties);
   var names = GetOwnEnumerablePropertyNames(props);
-  var descriptors = new InternalArray();
+  var descriptors = new InternalPackedArray();
   for (var i = 0; i < names.length; i++) {
     descriptors.push(ToPropertyDescriptor(props[names[i]]));
   }