Avoid using a register for constant external array indices.
authorjkummerow@chromium.org <jkummerow@chromium.org@ce2b1a6d-e550-0410-aec6-3dcde31c8c00>
Tue, 10 May 2011 15:25:17 +0000 (15:25 +0000)
committerjkummerow@chromium.org <jkummerow@chromium.org@ce2b1a6d-e550-0410-aec6-3dcde31c8c00>
Tue, 10 May 2011 15:25:17 +0000 (15:25 +0000)
This CL is based on and obsoletes CL 6879037.

TEST=mjsunit/external-array.js

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

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

12 files changed:
src/arm/lithium-arm.cc
src/arm/lithium-codegen-arm.cc
src/ia32/lithium-codegen-ia32.cc
src/ia32/lithium-codegen-ia32.h
src/ia32/lithium-ia32.cc
src/lithium.cc
src/lithium.h
src/x64/lithium-codegen-x64.cc
src/x64/lithium-codegen-x64.h
src/x64/lithium-x64.cc
test/cctest/test-api.cc
test/mjsunit/external-array.js

index 417927f51ec127ab36bc33e3175fde79f94b9c6b..b6531ca5b36612844d90931487b449c188a9c97c 100644 (file)
@@ -1861,7 +1861,7 @@ LInstruction* LChunkBuilder::DoLoadKeyedSpecializedArrayElement(
                                      array_type == kExternalDoubleArray)));
   ASSERT(instr->key()->representation().IsInteger32());
   LOperand* external_pointer = UseRegister(instr->external_pointer());
-  LOperand* key = UseRegister(instr->key());
+  LOperand* key = UseRegisterOrConstant(instr->key());
   LLoadKeyedSpecializedArrayElement* result =
       new LLoadKeyedSpecializedArrayElement(external_pointer, key);
   LInstruction* load_instr = DefineAsRegister(result);
@@ -1919,7 +1919,7 @@ LInstruction* LChunkBuilder::DoStoreKeyedSpecializedArrayElement(
   LOperand* val = val_is_temp_register
       ? UseTempRegister(instr->value())
       : UseRegister(instr->value());
-  LOperand* key = UseRegister(instr->key());
+  LOperand* key = UseRegisterOrConstant(instr->key());
 
   return new LStoreKeyedSpecializedArrayElement(external_pointer,
                                                 key,
index b1412ae896988e0d8e17a537134770d05c486c9b..90f4f3d5fe3982bd4aacf5f4f7ca93b2e9eb281c 100644 (file)
@@ -2484,40 +2484,56 @@ void LCodeGen::DoLoadKeyedFastElement(LLoadKeyedFastElement* instr) {
 void LCodeGen::DoLoadKeyedSpecializedArrayElement(
     LLoadKeyedSpecializedArrayElement* instr) {
   Register external_pointer = ToRegister(instr->external_pointer());
-  Register key = ToRegister(instr->key());
+  Register key = no_reg;
   ExternalArrayType array_type = instr->array_type();
-  if (array_type == kExternalFloatArray) {
-    CpuFeatures::Scope scope(VFP3);
-    DwVfpRegister result(ToDoubleRegister(instr->result()));
-    __ add(scratch0(), external_pointer, Operand(key, LSL, 2));
-    __ vldr(result.low(), scratch0(), 0);
-    __ vcvt_f64_f32(result, result.low());
-  } else if (array_type == kExternalDoubleArray) {
+  bool key_is_constant = instr->key()->IsConstantOperand();
+  int constant_key = 0;
+  if (key_is_constant) {
+    constant_key = ToInteger32(LConstantOperand::cast(instr->key()));
+    if (constant_key & 0xF0000000) {
+      Abort("array index constant value too big.");
+    }
+  } else {
+    key = ToRegister(instr->key());
+  }
+  int shift_size = ExternalArrayTypeToShiftSize(array_type);
+
+  if (array_type == kExternalFloatArray || array_type == kExternalDoubleArray) {
     CpuFeatures::Scope scope(VFP3);
     DwVfpRegister result(ToDoubleRegister(instr->result()));
-    __ add(scratch0(), external_pointer, Operand(key, LSL, 3));
-    __ vldr(result, scratch0(), 0);
+    Operand operand(key_is_constant ? Operand(constant_key * (1 << shift_size))
+                                    : Operand(key, LSL, shift_size));
+    __ add(scratch0(), external_pointer, operand);
+    if (array_type == kExternalFloatArray) {
+      __ vldr(result.low(), scratch0(), 0);
+      __ vcvt_f64_f32(result, result.low());
+    } else  {  // i.e. array_type == kExternalDoubleArray
+      __ vldr(result, scratch0(), 0);
+    }
   } else {
     Register result(ToRegister(instr->result()));
+    MemOperand mem_operand(key_is_constant
+        ? MemOperand(external_pointer, constant_key * (1 << shift_size))
+        : MemOperand(external_pointer, key, LSL, shift_size));
     switch (array_type) {
       case kExternalByteArray:
-        __ ldrsb(result, MemOperand(external_pointer, key));
+        __ ldrsb(result, mem_operand);
         break;
       case kExternalUnsignedByteArray:
       case kExternalPixelArray:
-        __ ldrb(result, MemOperand(external_pointer, key));
+        __ ldrb(result, mem_operand);
         break;
       case kExternalShortArray:
-        __ ldrsh(result, MemOperand(external_pointer, key, LSL, 1));
+        __ ldrsh(result, mem_operand);
         break;
       case kExternalUnsignedShortArray:
-        __ ldrh(result, MemOperand(external_pointer, key, LSL, 1));
+        __ ldrh(result, mem_operand);
         break;
       case kExternalIntArray:
-        __ ldr(result, MemOperand(external_pointer, key, LSL, 2));
+        __ ldr(result, mem_operand);
         break;
       case kExternalUnsignedIntArray:
-        __ ldr(result, MemOperand(external_pointer, key, LSL, 2));
+        __ ldr(result, mem_operand);
         __ cmp(result, Operand(0x80000000));
         // TODO(danno): we could be more clever here, perhaps having a special
         // version of the stub that detects if the overflow case actually
@@ -3247,39 +3263,53 @@ void LCodeGen::DoStoreKeyedSpecializedArrayElement(
     LStoreKeyedSpecializedArrayElement* instr) {
 
   Register external_pointer = ToRegister(instr->external_pointer());
-  Register key = ToRegister(instr->key());
+  Register key = no_reg;
   ExternalArrayType array_type = instr->array_type();
+  bool key_is_constant = instr->key()->IsConstantOperand();
+  int constant_key = 0;
+  if (key_is_constant) {
+    constant_key = ToInteger32(LConstantOperand::cast(instr->key()));
+    if (constant_key & 0xF0000000) {
+      Abort("array index constant value too big.");
+    }
+  } else {
+    key = ToRegister(instr->key());
+  }
+  int shift_size = ExternalArrayTypeToShiftSize(array_type);
 
-  if (array_type == kExternalFloatArray) {
+  if (array_type == kExternalFloatArray || array_type == kExternalDoubleArray) {
     CpuFeatures::Scope scope(VFP3);
     DwVfpRegister value(ToDoubleRegister(instr->value()));
-    __ add(scratch0(), external_pointer, Operand(key, LSL, 2));
-    __ vcvt_f32_f64(double_scratch0().low(), value);
-    __ vstr(double_scratch0().low(), scratch0(), 0);
-  } else if (array_type == kExternalDoubleArray) {
-    CpuFeatures::Scope scope(VFP3);
-    DwVfpRegister value(ToDoubleRegister(instr->value()));
-    __ add(scratch0(), external_pointer, Operand(key, LSL, 3));
-    __ vstr(value, scratch0(), 0);
+    Operand operand(key_is_constant ? Operand(constant_key * (1 << shift_size))
+                                    : Operand(key, LSL, shift_size));
+    __ add(scratch0(), external_pointer, operand);
+    if (array_type == kExternalFloatArray) {
+      __ vcvt_f32_f64(double_scratch0().low(), value);
+      __ vstr(double_scratch0().low(), scratch0(), 0);
+    } else {  // i.e. array_type == kExternalDoubleArray
+      __ vstr(value, scratch0(), 0);
+    }
   } else {
     Register value(ToRegister(instr->value()));
+    MemOperand mem_operand(key_is_constant
+        ? MemOperand(external_pointer, constant_key * (1 << shift_size))
+        : MemOperand(external_pointer, key, LSL, shift_size));
     switch (array_type) {
       case kExternalPixelArray:
         // Clamp the value to [0..255].
         __ Usat(value, 8, Operand(value));
-        __ strb(value, MemOperand(external_pointer, key));
-        break;
+        // Fall through to the next case for the store instruction:
       case kExternalByteArray:
       case kExternalUnsignedByteArray:
-        __ strb(value, MemOperand(external_pointer, key));
+        __ strb(value, mem_operand);
         break;
       case kExternalShortArray:
       case kExternalUnsignedShortArray:
-        __ strh(value, MemOperand(external_pointer, key, LSL, 1));
+        __ strh(value, mem_operand);
         break;
       case kExternalIntArray:
       case kExternalUnsignedIntArray:
-        __ str(value, MemOperand(external_pointer, key, LSL, 2));
+        __ str(value, mem_operand);
         break;
       case kExternalFloatArray:
       case kExternalDoubleArray:
index 7f33b639e5e994cdebf53fb76bb7bb31b21369ce..91634961403391fc80745b8ca284f710f8629f5a 100644 (file)
@@ -2392,39 +2392,56 @@ void LCodeGen::DoLoadKeyedFastElement(LLoadKeyedFastElement* instr) {
 }
 
 
+Operand LCodeGen::BuildExternalArrayOperand(LOperand* external_pointer,
+                                            LOperand* key,
+                                            ExternalArrayType array_type) {
+  Register external_pointer_reg = ToRegister(external_pointer);
+  int shift_size = ExternalArrayTypeToShiftSize(array_type);
+  if (key->IsConstantOperand()) {
+    int constant_value = ToInteger32(LConstantOperand::cast(key));
+    if (constant_value & 0xF0000000) {
+      Abort("array index constant value too big");
+    }
+    return Operand(external_pointer_reg, constant_value * (1 << shift_size));
+  } else {
+    ScaleFactor scale_factor = static_cast<ScaleFactor>(shift_size);
+    return Operand(external_pointer_reg, ToRegister(key), scale_factor, 0);
+  }
+}
+
+
 void LCodeGen::DoLoadKeyedSpecializedArrayElement(
     LLoadKeyedSpecializedArrayElement* instr) {
-  Register external_pointer = ToRegister(instr->external_pointer());
-  Register key = ToRegister(instr->key());
   ExternalArrayType array_type = instr->array_type();
+  Operand operand(BuildExternalArrayOperand(instr->external_pointer(),
+                                            instr->key(), array_type));
   if (array_type == kExternalFloatArray) {
     XMMRegister result(ToDoubleRegister(instr->result()));
-    __ movss(result, Operand(external_pointer, key, times_4, 0));
+    __ movss(result, operand);
     __ cvtss2sd(result, result);
   } else if (array_type == kExternalDoubleArray) {
-    __ movdbl(ToDoubleRegister(instr->result()),
-              Operand(external_pointer, key, times_8, 0));
+    __ movdbl(ToDoubleRegister(instr->result()), operand);
   } else {
     Register result(ToRegister(instr->result()));
     switch (array_type) {
       case kExternalByteArray:
-        __ movsx_b(result, Operand(external_pointer, key, times_1, 0));
+        __ movsx_b(result, operand);
         break;
       case kExternalUnsignedByteArray:
       case kExternalPixelArray:
-        __ movzx_b(result, Operand(external_pointer, key, times_1, 0));
+        __ movzx_b(result, operand);
         break;
       case kExternalShortArray:
-        __ movsx_w(result, Operand(external_pointer, key, times_2, 0));
+        __ movsx_w(result, operand);
         break;
       case kExternalUnsignedShortArray:
-        __ movzx_w(result, Operand(external_pointer, key, times_2, 0));
+        __ movzx_w(result, operand);
         break;
       case kExternalIntArray:
-        __ mov(result, Operand(external_pointer, key, times_4, 0));
+        __ mov(result, operand);
         break;
       case kExternalUnsignedIntArray:
-        __ mov(result, Operand(external_pointer, key, times_4, 0));
+        __ mov(result, operand);
         __ test(result, Operand(result));
         // TODO(danno): we could be more clever here, perhaps having a special
         // version of the stub that detects if the overflow case actually
@@ -3108,15 +3125,14 @@ void LCodeGen::DoBoundsCheck(LBoundsCheck* instr) {
 
 void LCodeGen::DoStoreKeyedSpecializedArrayElement(
     LStoreKeyedSpecializedArrayElement* instr) {
-  Register external_pointer = ToRegister(instr->external_pointer());
-  Register key = ToRegister(instr->key());
   ExternalArrayType array_type = instr->array_type();
+  Operand operand(BuildExternalArrayOperand(instr->external_pointer(),
+                                            instr->key(), array_type));
   if (array_type == kExternalFloatArray) {
     __ cvtsd2ss(xmm0, ToDoubleRegister(instr->value()));
-    __ movss(Operand(external_pointer, key, times_4, 0), xmm0);
+    __ movss(operand, xmm0);
   } else if (array_type == kExternalDoubleArray) {
-    __ movdbl(Operand(external_pointer, key, times_8, 0),
-              ToDoubleRegister(instr->value()));
+    __ movdbl(operand, ToDoubleRegister(instr->value()));
   } else {
     Register value = ToRegister(instr->value());
     switch (array_type) {
@@ -3135,20 +3151,20 @@ void LCodeGen::DoStoreKeyedSpecializedArrayElement(
         __ setcc(negative, temp);  // 1 if negative, 0 if positive.
         __ dec_b(temp);  // 0 if negative, 255 if positive.
         __ bind(&done);
-        __ mov_b(Operand(external_pointer, key, times_1, 0), temp);
+        __ mov_b(operand, temp);
         break;
       }
       case kExternalByteArray:
       case kExternalUnsignedByteArray:
-        __ mov_b(Operand(external_pointer, key, times_1, 0), value);
+        __ mov_b(operand, value);
         break;
       case kExternalShortArray:
       case kExternalUnsignedShortArray:
-        __ mov_w(Operand(external_pointer, key, times_2, 0), value);
+        __ mov_w(operand, value);
         break;
       case kExternalIntArray:
       case kExternalUnsignedIntArray:
-        __ mov(Operand(external_pointer, key, times_4, 0), value);
+        __ mov(operand, value);
         break;
       case kExternalFloatArray:
       case kExternalDoubleArray:
index bd2ed47c34f3423014f4b67b864260d22f364878..68d173e83ab1bbab11147274745e3afcc49c1bdd 100644 (file)
@@ -229,6 +229,9 @@ class LCodeGen BASE_EMBEDDED {
   Register ToRegister(int index) const;
   XMMRegister ToDoubleRegister(int index) const;
   int ToInteger32(LConstantOperand* op) const;
+  Operand BuildExternalArrayOperand(LOperand* external_pointer,
+                                    LOperand* key,
+                                    ExternalArrayType array_type);
 
   // Specific math operations - used from DoUnaryMathOperation.
   void EmitIntegerMathAbs(LUnaryMathOperation* instr);
index 7329660e5898291c4456018ba6523ac121074615..9b61870781a3a56fb36537fd7b67a926cb64e162 100644 (file)
@@ -1895,7 +1895,7 @@ LInstruction* LChunkBuilder::DoLoadKeyedSpecializedArrayElement(
                                      array_type == kExternalDoubleArray)));
   ASSERT(instr->key()->representation().IsInteger32());
   LOperand* external_pointer = UseRegister(instr->external_pointer());
-  LOperand* key = UseRegister(instr->key());
+  LOperand* key = UseRegisterOrConstant(instr->key());
   LLoadKeyedSpecializedArrayElement* result =
       new LLoadKeyedSpecializedArrayElement(external_pointer,
                                             key);
@@ -1950,7 +1950,7 @@ LInstruction* LChunkBuilder::DoStoreKeyedSpecializedArrayElement(
   ASSERT(instr->key()->representation().IsInteger32());
 
   LOperand* external_pointer = UseRegister(instr->external_pointer());
-  LOperand* key = UseRegister(instr->key());
+  LOperand* key = UseRegisterOrConstant(instr->key());
   LOperand* temp = NULL;
 
   if (array_type == kExternalPixelArray) {
index aeac2db562ab01296b2c63680cf05a1ba49d8fb2..62b263be114698796fd2ec314404d35471aa490e 100644 (file)
@@ -166,4 +166,25 @@ void LPointerMap::PrintTo(StringStream* stream) {
 }
 
 
+int ExternalArrayTypeToShiftSize(ExternalArrayType type) {
+  switch (type) {
+    case kExternalByteArray:
+    case kExternalUnsignedByteArray:
+    case kExternalPixelArray:
+      return 0;
+    case kExternalShortArray:
+    case kExternalUnsignedShortArray:
+      return 1;
+    case kExternalIntArray:
+    case kExternalUnsignedIntArray:
+    case kExternalFloatArray:
+      return 2;
+    case kExternalDoubleArray:
+      return 3;
+  }
+  UNREACHABLE();
+  return 0;
+}
+
+
 } }  // namespace v8::internal
index c5486847dada8842302cebe5c98116aae67e56ee..a3e574d89e32c656c8db7bafef090ea57dfc37d2 100644 (file)
@@ -588,6 +588,10 @@ class DeepIterator BASE_EMBEDDED {
   ShallowIterator current_iterator_;
 };
 
+
+int ExternalArrayTypeToShiftSize(ExternalArrayType type);
+
+
 } }  // namespace v8::internal
 
 #endif  // V8_LITHIUM_H_
index f26db274575686f9c9ea81d9e19ebacd1e6bd6ed..a4ed28ee79912d7005d1aaffc34575c9b513da7d 100644 (file)
@@ -2403,39 +2403,56 @@ void LCodeGen::DoLoadKeyedFastElement(LLoadKeyedFastElement* instr) {
 }
 
 
+Operand LCodeGen::BuildExternalArrayOperand(LOperand* external_pointer,
+                                            LOperand* key,
+                                            ExternalArrayType array_type) {
+  Register external_pointer_reg = ToRegister(external_pointer);
+  int shift_size = ExternalArrayTypeToShiftSize(array_type);
+  if (key->IsConstantOperand()) {
+    int constant_value = ToInteger32(LConstantOperand::cast(key));
+    if (constant_value & 0xF0000000) {
+      Abort("array index constant value too big");
+    }
+    return Operand(external_pointer_reg, constant_value * (1 << shift_size));
+  } else {
+    ScaleFactor scale_factor = static_cast<ScaleFactor>(shift_size);
+    return Operand(external_pointer_reg, ToRegister(key), scale_factor, 0);
+  }
+}
+
+
 void LCodeGen::DoLoadKeyedSpecializedArrayElement(
     LLoadKeyedSpecializedArrayElement* instr) {
-  Register external_pointer = ToRegister(instr->external_pointer());
-  Register key = ToRegister(instr->key());
   ExternalArrayType array_type = instr->array_type();
+  Operand operand(BuildExternalArrayOperand(instr->external_pointer(),
+                                            instr->key(), array_type));
   if (array_type == kExternalFloatArray) {
     XMMRegister result(ToDoubleRegister(instr->result()));
-    __ movss(result, Operand(external_pointer, key, times_4, 0));
+    __ movss(result, operand);
     __ cvtss2sd(result, result);
   } else if (array_type == kExternalDoubleArray) {
-    __ movsd(ToDoubleRegister(instr->result()),
-             Operand(external_pointer, key, times_8, 0));
+    __ movsd(ToDoubleRegister(instr->result()), operand);
   } else {
     Register result(ToRegister(instr->result()));
     switch (array_type) {
       case kExternalByteArray:
-        __ movsxbq(result, Operand(external_pointer, key, times_1, 0));
+        __ movsxbq(result, operand);
         break;
       case kExternalUnsignedByteArray:
       case kExternalPixelArray:
-        __ movzxbq(result, Operand(external_pointer, key, times_1, 0));
+        __ movzxbq(result, operand);
         break;
       case kExternalShortArray:
-        __ movsxwq(result, Operand(external_pointer, key, times_2, 0));
+        __ movsxwq(result, operand);
         break;
       case kExternalUnsignedShortArray:
-        __ movzxwq(result, Operand(external_pointer, key, times_2, 0));
+        __ movzxwq(result, operand);
         break;
       case kExternalIntArray:
-        __ movsxlq(result, Operand(external_pointer, key, times_4, 0));
+        __ movsxlq(result, operand);
         break;
       case kExternalUnsignedIntArray:
-        __ movl(result, Operand(external_pointer, key, times_4, 0));
+        __ movl(result, operand);
         __ testl(result, result);
         // TODO(danno): we could be more clever here, perhaps having a special
         // version of the stub that detects if the overflow case actually
@@ -3097,16 +3114,15 @@ void LCodeGen::DoStoreNamedGeneric(LStoreNamedGeneric* instr) {
 
 void LCodeGen::DoStoreKeyedSpecializedArrayElement(
     LStoreKeyedSpecializedArrayElement* instr) {
-  Register external_pointer = ToRegister(instr->external_pointer());
-  Register key = ToRegister(instr->key());
   ExternalArrayType array_type = instr->array_type();
+  Operand operand(BuildExternalArrayOperand(instr->external_pointer(),
+                                            instr->key(), array_type));
   if (array_type == kExternalFloatArray) {
     XMMRegister value(ToDoubleRegister(instr->value()));
     __ cvtsd2ss(value, value);
-    __ movss(Operand(external_pointer, key, times_4, 0), value);
+    __ movss(operand, value);
   } else if (array_type == kExternalDoubleArray) {
-    __ movsd(Operand(external_pointer, key, times_8, 0),
-             ToDoubleRegister(instr->value()));
+    __ movsd(operand, ToDoubleRegister(instr->value()));
   } else {
     Register value(ToRegister(instr->value()));
     switch (array_type) {
@@ -3118,20 +3134,20 @@ void LCodeGen::DoStoreKeyedSpecializedArrayElement(
           __ setcc(negative, value);  // 1 if negative, 0 if positive.
           __ decb(value);  // 0 if negative, 255 if positive.
           __ bind(&done);
-          __ movb(Operand(external_pointer, key, times_1, 0), value);
+          __ movb(operand, value);
         }
         break;
       case kExternalByteArray:
       case kExternalUnsignedByteArray:
-        __ movb(Operand(external_pointer, key, times_1, 0), value);
+        __ movb(operand, value);
         break;
       case kExternalShortArray:
       case kExternalUnsignedShortArray:
-        __ movw(Operand(external_pointer, key, times_2, 0), value);
+        __ movw(operand, value);
         break;
       case kExternalIntArray:
       case kExternalUnsignedIntArray:
-        __ movl(Operand(external_pointer, key, times_4, 0), value);
+        __ movl(operand, value);
         break;
       case kExternalFloatArray:
       case kExternalDoubleArray:
index 76abfa1a1b1769f02319fa252724486c4298cd95..8f2d30fca940356c55f66398dfe229c88fbc5118 100644 (file)
@@ -214,6 +214,9 @@ class LCodeGen BASE_EMBEDDED {
 
   Register ToRegister(int index) const;
   XMMRegister ToDoubleRegister(int index) const;
+  Operand BuildExternalArrayOperand(LOperand* external_pointer,
+                                    LOperand* key,
+                                    ExternalArrayType array_type);
 
   // Specific math operations - used from DoUnaryMathOperation.
   void EmitIntegerMathAbs(LUnaryMathOperation* instr);
index 7ca7c05c4c1d92ac391843c0a4875087dd0b2645..0e18b1c93e714fb50addc038c438ac2a64e9d702 100644 (file)
@@ -1851,7 +1851,7 @@ LInstruction* LChunkBuilder::DoLoadKeyedSpecializedArrayElement(
                                      array_type == kExternalDoubleArray)));
   ASSERT(instr->key()->representation().IsInteger32());
   LOperand* external_pointer = UseRegister(instr->external_pointer());
-  LOperand* key = UseRegister(instr->key());
+  LOperand* key = UseRegisterOrConstant(instr->key());
   LLoadKeyedSpecializedArrayElement* result =
       new LLoadKeyedSpecializedArrayElement(external_pointer, key);
   LInstruction* load_instr = DefineAsRegister(result);
@@ -1908,7 +1908,7 @@ LInstruction* LChunkBuilder::DoStoreKeyedSpecializedArrayElement(
   LOperand* val = val_is_temp_register
       ? UseTempRegister(instr->value())
       : UseRegister(instr->value());
-  LOperand* key = UseRegister(instr->key());
+  LOperand* key = UseRegisterOrConstant(instr->key());
 
   return new LStoreKeyedSpecializedArrayElement(external_pointer,
                                                 key,
index 4a0e595b68922fc78acc183aa8dbd0a2076730ca..17ba1813b42f9e9210c32cbe7ed5cf15e85ca7fb 100644 (file)
@@ -11953,35 +11953,6 @@ static void ExternalArrayTestHelper(v8::ExternalArrayType array_type,
     CHECK_EQ(true, result->BooleanValue());
   }
 
-  // Test crankshaft external array loads
-  for (int i = 0; i < kElementCount; i++) {
-    array->set(i, static_cast<ElementType>(i));
-  }
-  result = CompileRun("function ee_load_test_func(sum) {"
-                      " for (var i = 0; i < 40; ++i)"
-                      "   sum += ext_array[i];"
-                      " return sum;"
-                      "}"
-                      "sum=0;"
-                      "for (var i=0;i<10000;++i) {"
-                      "  sum=ee_load_test_func(sum);"
-                      "}"
-                      "sum;");
-  CHECK_EQ(7800000, result->Int32Value());
-
-  // Test crankshaft external array stores
-  result = CompileRun("function ee_store_test_func(sum) {"
-                      " for (var i = 0; i < 40; ++i)"
-                      "   sum += ext_array[i] = i;"
-                      " return sum;"
-                      "}"
-                      "sum=0;"
-                      "for (var i=0;i<10000;++i) {"
-                      "  sum=ee_store_test_func(sum);"
-                      "}"
-                      "sum;");
-  CHECK_EQ(7800000, result->Int32Value());
-
   for (int i = 0; i < kElementCount; i++) {
     array->set(i, static_cast<ElementType>(i));
   }
index 71f9b84e90153af923c57404e7c1ac777494e925..f03f5799fa4d6c2ccd18a1fa6dec62b48b6d8a21 100644 (file)
@@ -25,7 +25,7 @@
 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 
-// Flags: --allow-natives-syntax
+// Flags: --allow-natives-syntax --expose-gc
 
 // This is a regression test for overlapping key and value registers.
 function f(a) {
@@ -43,15 +43,6 @@ f(a);
 assertEquals(0, a[0]);
 assertEquals(0, a[1]);
 
-// Test the correct behavior of the |length| property (which is read-only).
-a = new Int32Array(42);
-assertEquals(42, a.length);
-a.length = 2;
-assertEquals(42, a.length);
-assertTrue(delete a.length);
-a.length = 2
-assertEquals(2, a.length);
-
 // Test the correct behavior of the |BYTES_PER_ELEMENT| property (which is
 // "constant", but not read-only).
 a = new Int32Array(2);
@@ -88,3 +79,72 @@ for (var i = 0; i < 5; i++) {
 %OptimizeFunctionOnNextCall(get);
 assertEquals(2.5, get(array, 0));
 assertEquals(3.5, get(array, 1));
+
+// Test loads and stores.
+types = [Int8Array, Uint8Array, Int16Array, Uint16Array, Int32Array,
+         Uint32Array, PixelArray, Float32Array, Float64Array];
+
+const kElementCount = 40;
+
+function test_load(array, sum) {
+  for (var i = 0; i < kElementCount; i++) {
+    sum += array[i];
+  }
+  return sum;
+}
+
+function test_load_const_key(array, sum) {
+  sum += array[0];
+  sum += array[1];
+  sum += array[2];
+  return sum;
+}
+
+function test_store(array, sum) {
+  for (var i = 0; i < kElementCount; i++) {
+    sum += array[i] = i+1;
+  }
+  return sum;
+}
+
+function test_store_const_key(array, sum) {
+  sum += array[0] = 1;
+  sum += array[1] = 2;
+  sum += array[2] = 3;
+  return sum;
+}
+
+function run_test(test_func, array, expected_sum_per_run) {
+  for (var i = 0; i < 5; i++) test_func(array, 0);
+  %OptimizeFunctionOnNextCall(test_func);
+  const kRuns = 10;
+  var sum = 0;
+  for (var i = 0; i < kRuns; i++) {
+    sum = test_func(array, sum);
+  }
+  assertEquals(sum, expected_sum_per_run * kRuns);
+  %DeoptimizeFunction(test_func);
+  gc();  // Makes V8 forget about type information for test_func.
+}
+
+for (var t = 0; t < types.length; t++) {
+  var type = types[t];
+  var a = new type(kElementCount);
+  for (var i = 0; i < kElementCount; i++) {
+    a[i] = i;
+  }
+  
+  // Run test functions defined above.
+  run_test(test_load, a, 780);
+  run_test(test_load_const_key, a, 3);
+  run_test(test_store, a, 820);
+  run_test(test_store_const_key, a, 6);
+  
+  // Test the correct behavior of the |length| property (which is read-only).
+  assertEquals(kElementCount, a.length);
+  a.length = 2;
+  assertEquals(kElementCount, a.length);
+  assertTrue(delete a.length);
+  a.length = 2
+  assertEquals(2, a.length);
+}