Activate smi-only optimizations for large array literals.
authordanno@chromium.org <danno@chromium.org@ce2b1a6d-e550-0410-aec6-3dcde31c8c00>
Mon, 10 Oct 2011 08:31:06 +0000 (08:31 +0000)
committerdanno@chromium.org <danno@chromium.org@ce2b1a6d-e550-0410-aec6-3dcde31c8c00>
Mon, 10 Oct 2011 08:31:06 +0000 (08:31 +0000)
BUG=none
TEST=none

Review URL: http://codereview.chromium.org/8177005

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

14 files changed:
src/arm/full-codegen-arm.cc
src/arm/ic-arm.cc
src/arm/stub-cache-arm.cc
src/builtins.cc
src/hydrogen.cc
src/ia32/full-codegen-ia32.cc
src/ia32/ic-ia32.cc
src/ia32/stub-cache-ia32.cc
src/objects-inl.h
src/objects.cc
src/runtime.cc
src/x64/full-codegen-x64.cc
src/x64/ic-x64.cc
src/x64/stub-cache-x64.cc

index ba21802..f9a880f 100644 (file)
@@ -1524,12 +1524,10 @@ void FullCodeGenerator::VisitArrayLiteral(ArrayLiteral* expr) {
     __ RecordWriteField(
         r1, offset, result_register(), r2, kLRHasBeenSaved, kDontSaveFPRegs,
         EMIT_REMEMBERED_SET, OMIT_SMI_CHECK);
-    if (FLAG_smi_only_arrays) {
-      __ ldr(r3, FieldMemOperand(r1, HeapObject::kMapOffset));
-      __ CheckFastSmiOnlyElements(r3, r2, &no_map_change);
-      __ push(r6);  // Copy of array literal.
-      __ CallRuntime(Runtime::kNonSmiElementStored, 1);
-    }
+    __ ldr(r3, FieldMemOperand(r1, HeapObject::kMapOffset));
+    __ CheckFastSmiOnlyElements(r3, r2, &no_map_change);
+    __ push(r6);  // Copy of array literal.
+    __ CallRuntime(Runtime::kNonSmiElementStored, 1);
     __ bind(&no_map_change);
 
     PrepareForBailoutForId(expr->GetIdForElement(i), NO_REGISTERS);
index 34807c3..6e0badc 100644 (file)
@@ -1380,10 +1380,8 @@ void KeyedStoreIC::GenerateGeneric(MacroAssembler* masm,
   __ Ret();
 
   __ bind(&non_smi_value);
-  if (FLAG_smi_only_arrays) {
-    // Escape to slow case when writing non-smi into smi-only array.
-    __ CheckFastObjectElements(receiver_map, scratch_value, &slow);
-  }
+  // Escape to slow case when writing non-smi into smi-only array.
+  __ CheckFastObjectElements(receiver_map, scratch_value, &slow);
   // Fast elements array, store the value to the elements backing store.
   __ add(address, elements, Operand(FixedArray::kHeaderSize - kHeapObjectTag));
   __ add(address, address, Operand(key, LSL, kPointerSizeLog2 - kSmiTagSize));
index 5b1f12c..09ecc79 100644 (file)
@@ -1618,10 +1618,8 @@ MaybeObject* CallStubCompiler::CompileArrayPushCall(Object* object,
 
       __ bind(&with_write_barrier);
 
-      if (FLAG_smi_only_arrays) {
-        __ ldr(r6, FieldMemOperand(receiver, HeapObject::kMapOffset));
-        __ CheckFastSmiOnlyElements(r6, r6, &call_builtin);
-      }
+      __ ldr(r6, FieldMemOperand(receiver, HeapObject::kMapOffset));
+      __ CheckFastSmiOnlyElements(r6, r6, &call_builtin);
 
       // Save new length.
       __ str(r0, FieldMemOperand(receiver, JSArray::kLengthOffset));
@@ -1652,15 +1650,13 @@ MaybeObject* CallStubCompiler::CompileArrayPushCall(Object* object,
       }
 
       __ ldr(r2, MemOperand(sp, (argc - 1) * kPointerSize));
-      if (FLAG_smi_only_arrays) {
-        // Growing elements that are SMI-only requires special handling in case
-        // the new element is non-Smi. For now, delegate to the builtin.
-        Label no_fast_elements_check;
-        __ JumpIfSmi(r2, &no_fast_elements_check);
-        __ ldr(r7, FieldMemOperand(receiver, HeapObject::kMapOffset));
-        __ CheckFastObjectElements(r7, r7, &call_builtin);
-        __ bind(&no_fast_elements_check);
-      }
+      // Growing elements that are SMI-only requires special handling in case
+      // the new element is non-Smi. For now, delegate to the builtin.
+      Label no_fast_elements_check;
+      __ JumpIfSmi(r2, &no_fast_elements_check);
+      __ ldr(r7, FieldMemOperand(receiver, HeapObject::kMapOffset));
+      __ CheckFastObjectElements(r7, r7, &call_builtin);
+      __ bind(&no_fast_elements_check);
 
       Isolate* isolate = masm()->isolate();
       ExternalReference new_space_allocation_top =
index 3905e9e..31fcd68 100644 (file)
@@ -242,11 +242,9 @@ BUILTIN(ArrayCodeGeneric) {
   }
 
   // Set length and elements on the array.
-  if (FLAG_smi_only_arrays) {
-    MaybeObject* maybe_object =
-        array->EnsureCanContainElements(FixedArray::cast(obj));
-    if (maybe_object->IsFailure()) return maybe_object;
-  }
+  MaybeObject* maybe_object =
+      array->EnsureCanContainElements(FixedArray::cast(obj));
+  if (maybe_object->IsFailure()) return maybe_object;
 
   AssertNoAllocation no_gc;
   FixedArray* elms = FixedArray::cast(obj);
@@ -402,15 +400,36 @@ static bool ArrayPrototypeHasNoElements(Heap* heap,
 
 MUST_USE_RESULT
 static inline MaybeObject* EnsureJSArrayWithWritableFastElements(
-    Heap* heap, Object* receiver) {
+    Heap* heap, Object* receiver, Arguments* args, int first_added_arg) {
   if (!receiver->IsJSArray()) return NULL;
   JSArray* array = JSArray::cast(receiver);
   HeapObject* elms = array->elements();
-  if (elms->map() == heap->fixed_array_map()) return elms;
-  if (elms->map() == heap->fixed_cow_array_map()) {
-    return array->EnsureWritableFastElements();
+  Map* map = elms->map();
+  if (map == heap->fixed_array_map()) {
+    if (args == NULL || !array->HasFastSmiOnlyElements()) {
+      return elms;
+    }
+  } else if (map == heap->fixed_cow_array_map()) {
+    MaybeObject* maybe_writable_result = array->EnsureWritableFastElements();
+    if (args == NULL || !array->HasFastSmiOnlyElements() ||
+        maybe_writable_result->IsFailure()) {
+      return maybe_writable_result;
+    }
+  } else {
+    return NULL;
   }
-  return NULL;
+
+  // Need to ensure that the arguments passed in args can be contained in
+  // the array.
+  int args_length = args->length();
+  if (first_added_arg >= args_length) return array->elements();
+
+  MaybeObject* maybe_array = array->EnsureCanContainElements(
+      args,
+      first_added_arg,
+      args_length - first_added_arg);
+  if (maybe_array->IsFailure()) return maybe_array;
+  return array->elements();
 }
 
 
@@ -455,7 +474,7 @@ BUILTIN(ArrayPush) {
   Object* receiver = *args.receiver();
   Object* elms_obj;
   { MaybeObject* maybe_elms_obj =
-        EnsureJSArrayWithWritableFastElements(heap, receiver);
+        EnsureJSArrayWithWritableFastElements(heap, receiver, &args, 1);
     if (maybe_elms_obj == NULL) {
       return CallJsBuiltin(isolate, "ArrayPush", args);
     }
@@ -493,9 +512,6 @@ BUILTIN(ArrayPush) {
     elms = new_elms;
   }
 
-  MaybeObject* maybe = array->EnsureCanContainElements(&args, 1, to_add);
-  if (maybe->IsFailure()) return maybe;
-
   // Add the provided values.
   AssertNoAllocation no_gc;
   WriteBarrierMode mode = elms->GetWriteBarrierMode(no_gc);
@@ -518,7 +534,7 @@ BUILTIN(ArrayPop) {
   Object* receiver = *args.receiver();
   Object* elms_obj;
   { MaybeObject* maybe_elms_obj =
-        EnsureJSArrayWithWritableFastElements(heap, receiver);
+        EnsureJSArrayWithWritableFastElements(heap, receiver, NULL, 0);
     if (maybe_elms_obj == NULL) return CallJsBuiltin(isolate, "ArrayPop", args);
     if (!maybe_elms_obj->ToObject(&elms_obj)) return maybe_elms_obj;
   }
@@ -551,7 +567,7 @@ BUILTIN(ArrayShift) {
   Object* receiver = *args.receiver();
   Object* elms_obj;
   { MaybeObject* maybe_elms_obj =
-        EnsureJSArrayWithWritableFastElements(heap, receiver);
+        EnsureJSArrayWithWritableFastElements(heap, receiver, NULL, 0);
     if (maybe_elms_obj == NULL)
         return CallJsBuiltin(isolate, "ArrayShift", args);
     if (!maybe_elms_obj->ToObject(&elms_obj)) return maybe_elms_obj;
@@ -593,7 +609,7 @@ BUILTIN(ArrayUnshift) {
   Object* receiver = *args.receiver();
   Object* elms_obj;
   { MaybeObject* maybe_elms_obj =
-        EnsureJSArrayWithWritableFastElements(heap, receiver);
+        EnsureJSArrayWithWritableFastElements(heap, receiver, NULL, 0);
     if (maybe_elms_obj == NULL)
         return CallJsBuiltin(isolate, "ArrayUnshift", args);
     if (!maybe_elms_obj->ToObject(&elms_obj)) return maybe_elms_obj;
@@ -612,11 +628,9 @@ BUILTIN(ArrayUnshift) {
   // we should never hit this case.
   ASSERT(to_add <= (Smi::kMaxValue - len));
 
-  if (FLAG_smi_only_arrays) {
-    MaybeObject* maybe_object =
-        array->EnsureCanContainElements(&args, 1, to_add);
-    if (maybe_object->IsFailure()) return maybe_object;
-  }
+  MaybeObject* maybe_object =
+      array->EnsureCanContainElements(&args, 1, to_add);
+  if (maybe_object->IsFailure()) return maybe_object;
 
   if (new_length > elms->length()) {
     // New backing storage is needed.
@@ -745,11 +759,9 @@ BUILTIN(ArraySlice) {
   }
   FixedArray* result_elms = FixedArray::cast(result);
 
-  if (FLAG_smi_only_arrays) {
-    MaybeObject* maybe_object =
-        result_array->EnsureCanContainElements(result_elms);
-    if (maybe_object->IsFailure()) return maybe_object;
-  }
+  MaybeObject* maybe_object =
+      result_array->EnsureCanContainElements(result_elms);
+  if (maybe_object->IsFailure()) return maybe_object;
 
   AssertNoAllocation no_gc;
   CopyElements(heap, &no_gc, result_elms, 0, elms, k, result_len);
@@ -768,7 +780,7 @@ BUILTIN(ArraySplice) {
   Object* receiver = *args.receiver();
   Object* elms_obj;
   { MaybeObject* maybe_elms_obj =
-        EnsureJSArrayWithWritableFastElements(heap, receiver);
+        EnsureJSArrayWithWritableFastElements(heap, receiver, &args, 3);
     if (maybe_elms_obj == NULL)
         return CallJsBuiltin(isolate, "ArraySplice", args);
     if (!maybe_elms_obj->ToObject(&elms_obj)) return maybe_elms_obj;
@@ -855,12 +867,6 @@ BUILTIN(ArraySplice) {
   }
 
   int item_count = (n_arguments > 1) ? (n_arguments - 2) : 0;
-
-  if (FLAG_smi_only_arrays) {
-    MaybeObject* maybe = array->EnsureCanContainElements(&args, 3, item_count);
-    if (maybe->IsFailure()) return maybe;
-  }
-
   int new_length = len - actual_delete_count + item_count;
 
   bool elms_changed = false;
@@ -997,15 +1003,13 @@ BUILTIN(ArrayConcat) {
   }
   FixedArray* result_elms = FixedArray::cast(result);
 
-  if (FLAG_smi_only_arrays) {
+  // Ensure element type transitions happen before copying elements in.
+  if (result_array->HasFastSmiOnlyElements()) {
     for (int i = 0; i < n_arguments; i++) {
       JSArray* array = JSArray::cast(args[i]);
-      int len = Smi::cast(array->length())->value();
-      if (len > 0) {
-        FixedArray* elms = FixedArray::cast(array->elements());
-        MaybeObject* maybe_object =
-            result_array->EnsureCanContainElements(elms);
-        if (maybe_object->IsFailure()) return maybe_object;
+      if (!array->HasFastSmiOnlyElements()) {
+        result_array->EnsureCanContainNonSmiElements();
+        break;
       }
     }
   }
index 64a6ae5..25e0a3d 100644 (file)
@@ -3346,46 +3346,42 @@ void HGraphBuilder::VisitArrayLiteral(ArrayLiteral* expr) {
     HValue* key = AddInstruction(
         new(zone()) HConstant(Handle<Object>(Smi::FromInt(i)),
                               Representation::Integer32()));
-    if (FLAG_smi_only_arrays) {
-      HInstruction* elements_kind =
-          AddInstruction(new(zone()) HElementsKind(literal));
-      HBasicBlock* store_fast = graph()->CreateBasicBlock();
-      // Two empty blocks to satisfy edge split form.
-      HBasicBlock* store_fast_edgesplit1 = graph()->CreateBasicBlock();
-      HBasicBlock* store_fast_edgesplit2 = graph()->CreateBasicBlock();
-      HBasicBlock* store_generic = graph()->CreateBasicBlock();
-      HBasicBlock* check_smi_only_elements = graph()->CreateBasicBlock();
-      HBasicBlock* join = graph()->CreateBasicBlock();
-
-      HIsSmiAndBranch* smicheck = new(zone()) HIsSmiAndBranch(value);
-      smicheck->SetSuccessorAt(0, store_fast_edgesplit1);
-      smicheck->SetSuccessorAt(1, check_smi_only_elements);
-      current_block()->Finish(smicheck);
-      store_fast_edgesplit1->Finish(new(zone()) HGoto(store_fast));
-
-      set_current_block(check_smi_only_elements);
-      HCompareConstantEqAndBranch* smi_elements_check =
-          new(zone()) HCompareConstantEqAndBranch(elements_kind,
-                                                  FAST_SMI_ONLY_ELEMENTS,
-                                                  Token::EQ_STRICT);
-      smi_elements_check->SetSuccessorAt(0, store_generic);
-      smi_elements_check->SetSuccessorAt(1, store_fast_edgesplit2);
-      current_block()->Finish(smi_elements_check);
-      store_fast_edgesplit2->Finish(new(zone()) HGoto(store_fast));
-
-      set_current_block(store_fast);
-      AddInstruction(new(zone()) HStoreKeyedFastElement(elements, key, value));
-      store_fast->Goto(join);
-
-      set_current_block(store_generic);
-      AddInstruction(BuildStoreKeyedGeneric(literal, key, value));
-      store_generic->Goto(join);
-
-      join->SetJoinId(expr->id());
-      set_current_block(join);
-    } else {
-      AddInstruction(new(zone()) HStoreKeyedFastElement(elements, key, value));
-    }
+    HInstruction* elements_kind =
+        AddInstruction(new(zone()) HElementsKind(literal));
+    HBasicBlock* store_fast = graph()->CreateBasicBlock();
+    // Two empty blocks to satisfy edge split form.
+    HBasicBlock* store_fast_edgesplit1 = graph()->CreateBasicBlock();
+    HBasicBlock* store_fast_edgesplit2 = graph()->CreateBasicBlock();
+    HBasicBlock* store_generic = graph()->CreateBasicBlock();
+    HBasicBlock* check_smi_only_elements = graph()->CreateBasicBlock();
+    HBasicBlock* join = graph()->CreateBasicBlock();
+
+    HIsSmiAndBranch* smicheck = new(zone()) HIsSmiAndBranch(value);
+    smicheck->SetSuccessorAt(0, store_fast_edgesplit1);
+    smicheck->SetSuccessorAt(1, check_smi_only_elements);
+    current_block()->Finish(smicheck);
+    store_fast_edgesplit1->Finish(new(zone()) HGoto(store_fast));
+
+    set_current_block(check_smi_only_elements);
+    HCompareConstantEqAndBranch* smi_elements_check =
+        new(zone()) HCompareConstantEqAndBranch(elements_kind,
+                                                FAST_SMI_ONLY_ELEMENTS,
+                                                Token::EQ_STRICT);
+    smi_elements_check->SetSuccessorAt(0, store_generic);
+    smi_elements_check->SetSuccessorAt(1, store_fast_edgesplit2);
+    current_block()->Finish(smi_elements_check);
+    store_fast_edgesplit2->Finish(new(zone()) HGoto(store_fast));
+
+    set_current_block(store_fast);
+    AddInstruction(new(zone()) HStoreKeyedFastElement(elements, key, value));
+    store_fast->Goto(join);
+
+    set_current_block(store_generic);
+    AddInstruction(BuildStoreKeyedGeneric(literal, key, value));
+    store_generic->Goto(join);
+
+    join->SetJoinId(expr->id());
+    set_current_block(join);
 
     AddSimulate(expr->GetIdForElement(i));
   }
index b66711f..594aae1 100644 (file)
@@ -1505,12 +1505,10 @@ void FullCodeGenerator::VisitArrayLiteral(ArrayLiteral* expr) {
                         kDontSaveFPRegs,
                         EMIT_REMEMBERED_SET,
                         OMIT_SMI_CHECK);
-    if (FLAG_smi_only_arrays) {
-      __ mov(edi, FieldOperand(ebx, JSObject::kMapOffset));
-      __ CheckFastSmiOnlyElements(edi, &no_map_change, Label::kNear);
-      __ push(Operand(esp, 0));
-      __ CallRuntime(Runtime::kNonSmiElementStored, 1);
-    }
+    __ mov(edi, FieldOperand(ebx, JSObject::kMapOffset));
+    __ CheckFastSmiOnlyElements(edi, &no_map_change, Label::kNear);
+    __ push(Operand(esp, 0));
+    __ CallRuntime(Runtime::kNonSmiElementStored, 1);
     __ bind(&no_map_change);
 
     PrepareForBailoutForId(expr->GetIdForElement(i), NO_REGISTERS);
index 4c72e56..8a98b17 100644 (file)
@@ -833,11 +833,9 @@ void KeyedStoreIC::GenerateGeneric(MacroAssembler* masm,
   __ ret(0);
 
   __ bind(&non_smi_value);
-  if (FLAG_smi_only_arrays) {
-    // Escape to slow case when writing non-smi into smi-only array.
-    __ mov(edi, FieldOperand(edx, HeapObject::kMapOffset));
-    __ CheckFastObjectElements(edi, &slow, Label::kNear);
-  }
+  // Escape to slow case when writing non-smi into smi-only array.
+  __ mov(edi, FieldOperand(edx, HeapObject::kMapOffset));
+  __ CheckFastObjectElements(edi, &slow, Label::kNear);
 
   // Fast elements array, store the value to the elements backing store.
   __ mov(CodeGenerator::FixedArrayElementOperand(ebx, ecx), eax);
index 9b8f096..53f9d5b 100644 (file)
@@ -1486,10 +1486,8 @@ MaybeObject* CallStubCompiler::CompileArrayPushCall(Object* object,
 
       __ bind(&with_write_barrier);
 
-      if (FLAG_smi_only_arrays) {
-        __ mov(edi, FieldOperand(edx, HeapObject::kMapOffset));
-        __ CheckFastObjectElements(edi, &call_builtin);
-      }
+      __ mov(edi, FieldOperand(edx, HeapObject::kMapOffset));
+      __ CheckFastObjectElements(edi, &call_builtin);
 
       // Save new length.
       __ mov(FieldOperand(edx, JSArray::kLengthOffset), eax);
@@ -1511,15 +1509,13 @@ MaybeObject* CallStubCompiler::CompileArrayPushCall(Object* object,
       }
 
       __ mov(edi, Operand(esp, argc * kPointerSize));
-      if (FLAG_smi_only_arrays) {
-        // Growing elements that are SMI-only requires special handling in case
-        // the new element is non-Smi. For now, delegate to the builtin.
-        Label no_fast_elements_check;
-        __ JumpIfSmi(edi, &no_fast_elements_check);
-        __ mov(esi, FieldOperand(edx, HeapObject::kMapOffset));
-        __ CheckFastObjectElements(esi, &call_builtin, Label::kFar);
-        __ bind(&no_fast_elements_check);
-      }
+      // Growing elements that are SMI-only requires special handling in case
+      // the new element is non-Smi. For now, delegate to the builtin.
+      Label no_fast_elements_check;
+      __ JumpIfSmi(edi, &no_fast_elements_check);
+      __ mov(esi, FieldOperand(edx, HeapObject::kMapOffset));
+      __ CheckFastObjectElements(esi, &call_builtin, Label::kFar);
+      __ bind(&no_fast_elements_check);
 
       // We could be lucky and the elements array could be at the top of
       // new-space.  In this case we can just grow it in place by moving the
index c579d37..cebf9be 100644 (file)
@@ -1306,8 +1306,7 @@ FixedArrayBase* JSObject::elements() {
 
 void JSObject::ValidateSmiOnlyElements() {
 #if DEBUG
-  if (FLAG_smi_only_arrays &&
-      map()->elements_kind() == FAST_SMI_ONLY_ELEMENTS) {
+  if (map()->elements_kind() == FAST_SMI_ONLY_ELEMENTS) {
     Heap* heap = GetHeap();
     // Don't use elements, since integrity checks will fail if there
     // are filler pointers in the array.
@@ -1332,8 +1331,7 @@ MaybeObject* JSObject::EnsureCanContainNonSmiElements() {
 #if DEBUG
   ValidateSmiOnlyElements();
 #endif
-  if (FLAG_smi_only_arrays &&
-      (map()->elements_kind() == FAST_SMI_ONLY_ELEMENTS)) {
+  if ((map()->elements_kind() == FAST_SMI_ONLY_ELEMENTS)) {
     Object* obj;
     MaybeObject* maybe_obj = GetElementsTransitionMap(FAST_ELEMENTS);
     if (!maybe_obj->ToObject(&obj)) return maybe_obj;
@@ -1345,8 +1343,7 @@ MaybeObject* JSObject::EnsureCanContainNonSmiElements() {
 
 MaybeObject* JSObject::EnsureCanContainElements(Object** objects,
                                                 uint32_t count) {
-  if (FLAG_smi_only_arrays &&
-      map()->elements_kind() == FAST_SMI_ONLY_ELEMENTS) {
+  if (map()->elements_kind() == FAST_SMI_ONLY_ELEMENTS) {
     for (uint32_t i = 0; i < count; ++i) {
       Object* current = *objects++;
       if (!current->IsSmi() && current != GetHeap()->the_hole_value()) {
@@ -1359,13 +1356,9 @@ MaybeObject* JSObject::EnsureCanContainElements(Object** objects,
 
 
 MaybeObject* JSObject::EnsureCanContainElements(FixedArray* elements) {
-  if (FLAG_smi_only_arrays) {
-    Object** objects = reinterpret_cast<Object**>(
-        FIELD_ADDR(elements, elements->OffsetOfElementAt(0)));
-    return EnsureCanContainElements(objects, elements->length());
-  } else {
-    return this;
-  }
+  Object** objects = reinterpret_cast<Object**>(
+      FIELD_ADDR(elements, elements->OffsetOfElementAt(0)));
+  return EnsureCanContainElements(objects, elements->length());
 }
 
 
index 12bc67c..71c5d4e 100644 (file)
@@ -7765,7 +7765,6 @@ MaybeObject* JSObject::SetFastElementsCapacityAndLength(
   if (elements()->map() != heap->non_strict_arguments_elements_map()) {
     Object* object;
     bool has_fast_smi_only_elements =
-        FLAG_smi_only_arrays &&
         (set_capacity_mode == kAllowSmiOnlyElements) &&
         (elements()->map()->has_fast_smi_only_elements() ||
          elements() == heap->empty_fixed_array());
index f47e54a..3e04942 100644 (file)
@@ -422,6 +422,9 @@ static Handle<Object> CreateObjectLiteralBoilerplate(
 }
 
 
+static const int kSmiOnlyLiteralMinimumLength = 1024;
+
+
 static Handle<Object> CreateArrayLiteralBoilerplate(
     Isolate* isolate,
     Handle<FixedArray> literals,
@@ -431,6 +434,13 @@ static Handle<Object> CreateArrayLiteralBoilerplate(
       JSFunction::GlobalContextFromLiterals(*literals)->array_function());
   Handle<Object> object = isolate->factory()->NewJSObject(constructor);
 
+  if (elements->length() > kSmiOnlyLiteralMinimumLength) {
+    Handle<Map> smi_array_map = isolate->factory()->GetElementsTransitionMap(
+        Handle<JSObject>::cast(object),
+        FAST_SMI_ONLY_ELEMENTS);
+    HeapObject::cast(*object)->set_map(*smi_array_map);
+  }
+
   const bool is_cow =
       (elements->map() == isolate->heap()->fixed_cow_array_map());
   Handle<FixedArray> copied_elements =
@@ -440,21 +450,18 @@ static Handle<Object> CreateArrayLiteralBoilerplate(
   bool has_non_smi = false;
   if (is_cow) {
     // Copy-on-write arrays must be shallow (and simple).
-    if (FLAG_smi_only_arrays) {
-      for (int i = 0; i < content->length(); i++) {
-        Object* current = content->get(i);
-        ASSERT(!current->IsFixedArray());
-        if (!current->IsSmi() && !current->IsTheHole()) {
-          has_non_smi = true;
-        }
+    for (int i = 0; i < content->length(); i++) {
+      Object* current = content->get(i);
+      ASSERT(!current->IsFixedArray());
+      if (!current->IsSmi() && !current->IsTheHole()) {
+        has_non_smi = true;
       }
-    } else {
+    }
 #if DEBUG
-      for (int i = 0; i < content->length(); i++) {
-        ASSERT(!content->get(i)->IsFixedArray());
-      }
-#endif
+    for (int i = 0; i < content->length(); i++) {
+      ASSERT(!content->get(i)->IsFixedArray());
     }
+#endif
   } else {
     for (int i = 0; i < content->length(); i++) {
       Object* current = content->get(i);
@@ -479,10 +486,8 @@ static Handle<Object> CreateArrayLiteralBoilerplate(
   Handle<JSArray> js_object(Handle<JSArray>::cast(object));
   isolate->factory()->SetContent(js_object, content);
 
-  if (FLAG_smi_only_arrays) {
-    if (has_non_smi && js_object->HasFastSmiOnlyElements()) {
-      isolate->factory()->EnsureCanContainNonSmiElements(js_object);
-    }
+  if (has_non_smi && js_object->HasFastSmiOnlyElements()) {
+    isolate->factory()->EnsureCanContainNonSmiElements(js_object);
   }
 
   return object;
@@ -1661,7 +1666,7 @@ RUNTIME_FUNCTION(MaybeObject*,
 RUNTIME_FUNCTION(MaybeObject*, Runtime_NonSmiElementStored) {
   ASSERT(args.length() == 1);
   CONVERT_ARG_CHECKED(JSObject, object, 0);
-  if (FLAG_smi_only_arrays && object->HasFastSmiOnlyElements()) {
+  if (object->HasFastSmiOnlyElements()) {
     MaybeObject* maybe_map = object->GetElementsTransitionMap(FAST_ELEMENTS);
     Map* map;
     if (!maybe_map->To<Map>(&map)) return maybe_map;
index afcf50a..92732fa 100644 (file)
@@ -1473,12 +1473,10 @@ void FullCodeGenerator::VisitArrayLiteral(ArrayLiteral* expr) {
                         kDontSaveFPRegs,
                         EMIT_REMEMBERED_SET,
                         OMIT_SMI_CHECK);
-    if (FLAG_smi_only_arrays) {
-      __ movq(rdi, FieldOperand(rbx, JSObject::kMapOffset));
-      __ CheckFastSmiOnlyElements(rdi, &no_map_change, Label::kNear);
-      __ push(r8);
-      __ CallRuntime(Runtime::kNonSmiElementStored, 1);
-    }
+    __ movq(rdi, FieldOperand(rbx, JSObject::kMapOffset));
+    __ CheckFastSmiOnlyElements(rdi, &no_map_change, Label::kNear);
+    __ push(r8);
+    __ CallRuntime(Runtime::kNonSmiElementStored, 1);
     __ bind(&no_map_change);
 
     PrepareForBailoutForId(expr->GetIdForElement(i), NO_REGISTERS);
index 4ae1785..27a9667 100644 (file)
@@ -709,11 +709,9 @@ void KeyedStoreIC::GenerateGeneric(MacroAssembler* masm,
   __ ret(0);
 
   __ bind(&non_smi_value);
-  if (FLAG_smi_only_arrays) {
-    // Writing a non-smi, check whether array allows non-smi elements.
-    // r9: receiver's map
-    __ CheckFastObjectElements(r9, &slow, Label::kNear);
-  }
+  // Writing a non-smi, check whether array allows non-smi elements.
+  // r9: receiver's map
+  __ CheckFastObjectElements(r9, &slow, Label::kNear);
   __ lea(rcx,
          FieldOperand(rbx, rcx, times_pointer_size, FixedArray::kHeaderSize));
   __ movq(Operand(rcx, 0), rax);
index 14ac003..b08ae1d 100644 (file)
@@ -1460,10 +1460,8 @@ MaybeObject* CallStubCompiler::CompileArrayPushCall(Object* object,
 
       __ bind(&with_write_barrier);
 
-      if (FLAG_smi_only_arrays) {
-        __ movq(rdi, FieldOperand(rdx, HeapObject::kMapOffset));
-        __ CheckFastObjectElements(rdi, &call_builtin);
-      }
+      __ movq(rdi, FieldOperand(rdx, HeapObject::kMapOffset));
+      __ CheckFastObjectElements(rdi, &call_builtin);
 
       // Save new length.
       __ Integer32ToSmiField(FieldOperand(rdx, JSArray::kLengthOffset), rax);
@@ -1486,15 +1484,13 @@ MaybeObject* CallStubCompiler::CompileArrayPushCall(Object* object,
       }
 
       __ movq(rdi, Operand(rsp, argc * kPointerSize));
-      if (FLAG_smi_only_arrays) {
-        // Growing elements that are SMI-only requires special handling in case
-        // the new element is non-Smi. For now, delegate to the builtin.
-        Label no_fast_elements_check;
-        __ JumpIfSmi(rdi, &no_fast_elements_check);
-        __ movq(rsi, FieldOperand(rdx, HeapObject::kMapOffset));
-        __ CheckFastObjectElements(rsi, &call_builtin, Label::kFar);
-        __ bind(&no_fast_elements_check);
-      }
+      // Growing elements that are SMI-only requires special handling in case
+      // the new element is non-Smi. For now, delegate to the builtin.
+      Label no_fast_elements_check;
+      __ JumpIfSmi(rdi, &no_fast_elements_check);
+      __ movq(rsi, FieldOperand(rdx, HeapObject::kMapOffset));
+      __ CheckFastObjectElements(rsi, &call_builtin, Label::kFar);
+      __ bind(&no_fast_elements_check);
 
       ExternalReference new_space_allocation_top =
           ExternalReference::new_space_allocation_top_address(isolate());