Revision: 8901
Author: [email protected]
Date: Thu Aug 11 07:00:16 2011
Log: Create a common base class for Fixed-, FixedDouble- and
ExternalArrays.
Also unify Crankshaft code to load array length.
BUG=v8:1493
TEST=external-arrays.js
Review URL: http://codereview.chromium.org/7600025
http://code.google.com/p/v8/source/detail?r=8901
Modified:
/branches/bleeding_edge/src/arm/lithium-arm.cc
/branches/bleeding_edge/src/arm/lithium-arm.h
/branches/bleeding_edge/src/arm/lithium-codegen-arm.cc
/branches/bleeding_edge/src/arm/stub-cache-arm.cc
/branches/bleeding_edge/src/hydrogen-instructions.h
/branches/bleeding_edge/src/hydrogen.cc
/branches/bleeding_edge/src/ia32/lithium-codegen-ia32.cc
/branches/bleeding_edge/src/ia32/lithium-ia32.cc
/branches/bleeding_edge/src/ia32/lithium-ia32.h
/branches/bleeding_edge/src/ia32/stub-cache-ia32.cc
/branches/bleeding_edge/src/mips/stub-cache-mips.cc
/branches/bleeding_edge/src/objects-inl.h
/branches/bleeding_edge/src/objects.h
/branches/bleeding_edge/src/x64/lithium-codegen-x64.cc
/branches/bleeding_edge/src/x64/lithium-x64.cc
/branches/bleeding_edge/src/x64/lithium-x64.h
/branches/bleeding_edge/src/x64/stub-cache-x64.cc
/branches/bleeding_edge/test/mjsunit/external-array.js
=======================================
--- /branches/bleeding_edge/src/arm/lithium-arm.cc Thu Aug 11 00:22:16 2011
+++ /branches/bleeding_edge/src/arm/lithium-arm.cc Thu Aug 11 07:00:16 2011
@@ -1509,16 +1509,10 @@
}
-LInstruction* LChunkBuilder::DoExternalArrayLength(
- HExternalArrayLength* instr) {
+LInstruction* LChunkBuilder::DoFixedArrayBaseLength(
+ HFixedArrayBaseLength* instr) {
LOperand* array = UseRegisterAtStart(instr->value());
- return DefineAsRegister(new LExternalArrayLength(array));
-}
-
-
-LInstruction* LChunkBuilder::DoFixedArrayLength(HFixedArrayLength* instr) {
- LOperand* array = UseRegisterAtStart(instr->value());
- return DefineAsRegister(new LFixedArrayLength(array));
+ return DefineAsRegister(new LFixedArrayBaseLength(array));
}
=======================================
--- /branches/bleeding_edge/src/arm/lithium-arm.h Tue Jul 19 06:04:00 2011
+++ /branches/bleeding_edge/src/arm/lithium-arm.h Thu Aug 11 07:00:16 2011
@@ -92,8 +92,7 @@
V(DivI) \
V(DoubleToI) \
V(ElementsKind) \
- V(ExternalArrayLength) \
- V(FixedArrayLength) \
+ V(FixedArrayBaseLength) \
V(FunctionLiteral) \
V(GetCachedArrayIndex) \
V(GlobalObject) \
@@ -915,25 +914,15 @@
};
-class LExternalArrayLength: public LTemplateInstruction<1, 1, 0> {
+class LFixedArrayBaseLength: public LTemplateInstruction<1, 1, 0> {
public:
- explicit LExternalArrayLength(LOperand* value) {
+ explicit LFixedArrayBaseLength(LOperand* value) {
inputs_[0] = value;
}
-
DECLARE_CONCRETE_INSTRUCTION(ExternalArrayLength, "external-array-length")
- DECLARE_HYDROGEN_ACCESSOR(ExternalArrayLength)
-};
-
-
-class LFixedArrayLength: public LTemplateInstruction<1, 1, 0> {
- public:
- explicit LFixedArrayLength(LOperand* value) {
- inputs_[0] = value;
- }
-
- DECLARE_CONCRETE_INSTRUCTION(FixedArrayLength, "fixed-array-length")
- DECLARE_HYDROGEN_ACCESSOR(FixedArrayLength)
+ DECLARE_CONCRETE_INSTRUCTION(FixedArrayBaseLength,
+ "fixed-array-base-length")
+ DECLARE_HYDROGEN_ACCESSOR(FixedArrayBaseLength)
};
=======================================
--- /branches/bleeding_edge/src/arm/lithium-codegen-arm.cc Thu Aug 11
00:22:16 2011
+++ /branches/bleeding_edge/src/arm/lithium-codegen-arm.cc Thu Aug 11
07:00:16 2011
@@ -1378,17 +1378,10 @@
}
-void LCodeGen::DoExternalArrayLength(LExternalArrayLength* instr) {
+void LCodeGen::DoFixedArrayBaseLength(LFixedArrayBaseLength* instr) {
Register result = ToRegister(instr->result());
Register array = ToRegister(instr->InputAt(0));
- __ ldr(result, FieldMemOperand(array, ExternalArray::kLengthOffset));
-}
-
-
-void LCodeGen::DoFixedArrayLength(LFixedArrayLength* instr) {
- Register result = ToRegister(instr->result());
- Register array = ToRegister(instr->InputAt(0));
- __ ldr(result, FieldMemOperand(array, FixedArray::kLengthOffset));
+ __ ldr(result, FieldMemOperand(array, FixedArrayBase::kLengthOffset));
}
=======================================
--- /branches/bleeding_edge/src/arm/stub-cache-arm.cc Tue Aug 2 06:36:38
2011
+++ /branches/bleeding_edge/src/arm/stub-cache-arm.cc Thu Aug 11 07:00:16
2011
@@ -3489,9 +3489,9 @@
// Check that the index is in range.
__ ldr(ip, FieldMemOperand(r3, ExternalArray::kLengthOffset));
- __ cmp(ip, Operand(key, ASR, kSmiTagSize));
+ __ cmp(key, ip);
// Unsigned comparison catches both negative and too-large values.
- __ b(lo, &miss_force_generic);
+ __ b(hs, &miss_force_generic);
__ ldr(r3, FieldMemOperand(r3, ExternalArray::kExternalPointerOffset));
// r3: base pointer of external storage
@@ -3811,22 +3811,20 @@
// This stub is meant to be tail-jumped to, the receiver must already
// have been verified by the caller to not be a smi.
- __ ldr(r3, FieldMemOperand(receiver, JSObject::kElementsOffset));
-
// Check that the key is a smi.
__ JumpIfNotSmi(key, &miss_force_generic);
+ __ ldr(r3, FieldMemOperand(receiver, JSObject::kElementsOffset));
+
// Check that the index is in range
- __ SmiUntag(r4, key);
__ ldr(ip, FieldMemOperand(r3, ExternalArray::kLengthOffset));
- __ cmp(r4, ip);
+ __ cmp(key, ip);
// Unsigned comparison catches both negative and too-large values.
__ b(hs, &miss_force_generic);
// Handle both smis and HeapNumbers in the fast path. Go to the
// runtime for all other kinds of values.
// r3: external array.
- // r4: key (integer).
if (elements_kind == JSObject::EXTERNAL_PIXEL_ELEMENTS) {
// Double to pixel conversion is only implemented in the runtime for
now.
__ JumpIfNotSmi(value, &slow);
@@ -3837,32 +3835,32 @@
__ ldr(r3, FieldMemOperand(r3, ExternalArray::kExternalPointerOffset));
// r3: base pointer of external storage.
- // r4: key (integer).
// r5: value (integer).
switch (elements_kind) {
case JSObject::EXTERNAL_PIXEL_ELEMENTS:
// Clamp the value to [0..255].
__ Usat(r5, 8, Operand(r5));
- __ strb(r5, MemOperand(r3, r4, LSL, 0));
+ __ strb(r5, MemOperand(r3, key, LSR, 1));
break;
case JSObject::EXTERNAL_BYTE_ELEMENTS:
case JSObject::EXTERNAL_UNSIGNED_BYTE_ELEMENTS:
- __ strb(r5, MemOperand(r3, r4, LSL, 0));
+ __ strb(r5, MemOperand(r3, key, LSR, 1));
break;
case JSObject::EXTERNAL_SHORT_ELEMENTS:
case JSObject::EXTERNAL_UNSIGNED_SHORT_ELEMENTS:
- __ strh(r5, MemOperand(r3, r4, LSL, 1));
+ __ strh(r5, MemOperand(r3, key, LSL, 0));
break;
case JSObject::EXTERNAL_INT_ELEMENTS:
case JSObject::EXTERNAL_UNSIGNED_INT_ELEMENTS:
- __ str(r5, MemOperand(r3, r4, LSL, 2));
+ __ str(r5, MemOperand(r3, key, LSL, 1));
break;
case JSObject::EXTERNAL_FLOAT_ELEMENTS:
// Perform int-to-float conversion and store to memory.
+ __ SmiUntag(r4, key);
StoreIntAsFloat(masm, r3, r4, r5, r6, r7, r9);
break;
case JSObject::EXTERNAL_DOUBLE_ELEMENTS:
- __ add(r3, r3, Operand(r4, LSL, 3));
+ __ add(r3, r3, Operand(key, LSL, 2));
// r3: effective address of the double element
FloatingPointHelper::Destination destination;
if (CpuFeatures::IsSupported(VFP3)) {
@@ -3895,7 +3893,6 @@
if (elements_kind != JSObject::EXTERNAL_PIXEL_ELEMENTS) {
// r3: external array.
- // r4: index (integer).
__ bind(&check_heap_number);
__ CompareObjectType(value, r5, r6, HEAP_NUMBER_TYPE);
__ b(ne, &slow);
@@ -3903,7 +3900,6 @@
__ ldr(r3, FieldMemOperand(r3, ExternalArray::kExternalPointerOffset));
// r3: base pointer of external storage.
- // r4: key (integer).
// The WebGL specification leaves the behavior of storing NaN and
// +/-Infinity into integer arrays basically undefined. For more
@@ -3916,13 +3912,13 @@
// include -kHeapObjectTag into it.
__ sub(r5, r0, Operand(kHeapObjectTag));
__ vldr(d0, r5, HeapNumber::kValueOffset);
- __ add(r5, r3, Operand(r4, LSL, 2));
+ __ add(r5, r3, Operand(key, LSL, 1));
__ vcvt_f32_f64(s0, d0);
__ vstr(s0, r5, 0);
} else if (elements_kind == JSObject::EXTERNAL_DOUBLE_ELEMENTS) {
__ sub(r5, r0, Operand(kHeapObjectTag));
__ vldr(d0, r5, HeapNumber::kValueOffset);
- __ add(r5, r3, Operand(r4, LSL, 3));
+ __ add(r5, r3, Operand(key, LSL, 2));
__ vstr(d0, r5, 0);
} else {
// Hoisted load. vldr requires offset to be a multiple of 4 so we
can
@@ -3934,15 +3930,15 @@
switch (elements_kind) {
case JSObject::EXTERNAL_BYTE_ELEMENTS:
case JSObject::EXTERNAL_UNSIGNED_BYTE_ELEMENTS:
- __ strb(r5, MemOperand(r3, r4, LSL, 0));
+ __ strb(r5, MemOperand(r3, key, LSR, 1));
break;
case JSObject::EXTERNAL_SHORT_ELEMENTS:
case JSObject::EXTERNAL_UNSIGNED_SHORT_ELEMENTS:
- __ strh(r5, MemOperand(r3, r4, LSL, 1));
+ __ strh(r5, MemOperand(r3, key, LSL, 0));
break;
case JSObject::EXTERNAL_INT_ELEMENTS:
case JSObject::EXTERNAL_UNSIGNED_INT_ELEMENTS:
- __ str(r5, MemOperand(r3, r4, LSL, 2));
+ __ str(r5, MemOperand(r3, key, LSL, 1));
break;
case JSObject::EXTERNAL_PIXEL_ELEMENTS:
case JSObject::EXTERNAL_FLOAT_ELEMENTS:
@@ -4004,7 +4000,7 @@
__ orr(r5, r7, Operand(r9, LSL, kBinary32ExponentShift));
__ bind(&done);
- __ str(r5, MemOperand(r3, r4, LSL, 2));
+ __ str(r5, MemOperand(r3, key, LSL, 1));
// Entry registers are intact, r0 holds the value which is the
return
// value.
__ Ret();
@@ -4017,7 +4013,7 @@
__ orr(r5, r9, Operand(r6, LSR, kMantissaInLoWordShift));
__ b(&done);
} else if (elements_kind == JSObject::EXTERNAL_DOUBLE_ELEMENTS) {
- __ add(r7, r3, Operand(r4, LSL, 3));
+ __ add(r7, r3, Operand(key, LSL, 2));
// r7: effective address of destination element.
__ str(r6, MemOperand(r7, 0));
__ str(r5, MemOperand(r7, Register::kSizeInBytes));
@@ -4073,15 +4069,15 @@
switch (elements_kind) {
case JSObject::EXTERNAL_BYTE_ELEMENTS:
case JSObject::EXTERNAL_UNSIGNED_BYTE_ELEMENTS:
- __ strb(r5, MemOperand(r3, r4, LSL, 0));
+ __ strb(r5, MemOperand(r3, key, LSR, 1));
break;
case JSObject::EXTERNAL_SHORT_ELEMENTS:
case JSObject::EXTERNAL_UNSIGNED_SHORT_ELEMENTS:
- __ strh(r5, MemOperand(r3, r4, LSL, 1));
+ __ strh(r5, MemOperand(r3, key, LSL, 0));
break;
case JSObject::EXTERNAL_INT_ELEMENTS:
case JSObject::EXTERNAL_UNSIGNED_INT_ELEMENTS:
- __ str(r5, MemOperand(r3, r4, LSL, 2));
+ __ str(r5, MemOperand(r3, key, LSL, 1));
break;
case JSObject::EXTERNAL_PIXEL_ELEMENTS:
case JSObject::EXTERNAL_FLOAT_ELEMENTS:
=======================================
--- /branches/bleeding_edge/src/hydrogen-instructions.h Tue Jul 26 09:31:11
2011
+++ /branches/bleeding_edge/src/hydrogen-instructions.h Thu Aug 11 07:00:16
2011
@@ -104,8 +104,7 @@
V(Div) \
V(ElementsKind) \
V(EnterInlined) \
- V(ExternalArrayLength) \
- V(FixedArrayLength) \
+ V(FixedArrayBaseLength) \
V(ForceRepresentation) \
V(FunctionLiteral) \
V(GetCachedArrayIndex) \
@@ -1702,9 +1701,9 @@
};
-class HFixedArrayLength: public HUnaryOperation {
+class HFixedArrayBaseLength: public HUnaryOperation {
public:
- explicit HFixedArrayLength(HValue* value) : HUnaryOperation(value) {
+ explicit HFixedArrayBaseLength(HValue* value) : HUnaryOperation(value) {
set_representation(Representation::Tagged());
SetFlag(kUseGVN);
SetFlag(kDependsOnArrayLengths);
@@ -1714,28 +1713,7 @@
return Representation::Tagged();
}
- DECLARE_CONCRETE_INSTRUCTION(FixedArrayLength)
-
- protected:
- virtual bool DataEquals(HValue* other) { return true; }
-};
-
-
-class HExternalArrayLength: public HUnaryOperation {
- public:
- explicit HExternalArrayLength(HValue* value) : HUnaryOperation(value) {
- set_representation(Representation::Integer32());
- // The result of this instruction is idempotent as long as its inputs
don't
- // change. The length of a pixel array cannot change once set, so
it's not
- // necessary to introduce a kDependsOnArrayLengths or any other
dependency.
- SetFlag(kUseGVN);
- }
-
- virtual Representation RequiredInputRepresentation(int index) const {
- return Representation::Tagged();
- }
-
- DECLARE_CONCRETE_INSTRUCTION(ExternalArrayLength)
+ DECLARE_CONCRETE_INSTRUCTION(FixedArrayBaseLength)
protected:
virtual bool DataEquals(HValue* other) { return true; }
=======================================
--- /branches/bleeding_edge/src/hydrogen.cc Wed Aug 10 09:05:17 2011
+++ /branches/bleeding_edge/src/hydrogen.cc Thu Aug 11 07:00:16 2011
@@ -3940,7 +3940,7 @@
HInstruction* length = NULL;
HInstruction* checked_key = NULL;
if (map->has_external_array_elements()) {
- length = AddInstruction(new(zone()) HExternalArrayLength(elements));
+ length = AddInstruction(new(zone()) HFixedArrayBaseLength(elements));
checked_key = AddInstruction(new(zone()) HBoundsCheck(key, length));
HLoadExternalArrayPointer* external_elements =
new(zone()) HLoadExternalArrayPointer(elements);
@@ -3952,7 +3952,7 @@
if (map->instance_type() == JS_ARRAY_TYPE) {
length = AddInstruction(new(zone()) HJSArrayLength(object, mapcheck));
} else {
- length = AddInstruction(new(zone()) HFixedArrayLength(elements));
+ length = AddInstruction(new(zone()) HFixedArrayBaseLength(elements));
}
checked_key = AddInstruction(new(zone()) HBoundsCheck(key, length));
if (is_store) {
@@ -4024,7 +4024,7 @@
if (elements_kind == JSObject::FIRST_EXTERNAL_ARRAY_ELEMENTS_KIND
&& todo_external_array) {
HInstruction* length =
- AddInstruction(new(zone()) HExternalArrayLength(elements));
+ AddInstruction(new(zone()) HFixedArrayBaseLength(elements));
checked_key = AddInstruction(new(zone()) HBoundsCheck(key, length));
external_elements = new(zone()) HLoadExternalArrayPointer(elements);
AddInstruction(external_elements);
@@ -4088,7 +4088,7 @@
if_jsarray->Goto(join);
set_current_block(if_fastobject);
- length = AddInstruction(new(zone()) HFixedArrayLength(elements));
+ length = AddInstruction(new(zone())
HFixedArrayBaseLength(elements));
checked_key = AddInstruction(new(zone()) HBoundsCheck(key,
length));
if (is_store) {
if (fast_double_elements) {
=======================================
--- /branches/bleeding_edge/src/ia32/lithium-codegen-ia32.cc Thu Aug 11
00:22:16 2011
+++ /branches/bleeding_edge/src/ia32/lithium-codegen-ia32.cc Thu Aug 11
07:00:16 2011
@@ -1211,17 +1211,11 @@
}
-void LCodeGen::DoFixedArrayLength(LFixedArrayLength* instr) {
+void LCodeGen::DoFixedArrayBaseLength(
+ LFixedArrayBaseLength* instr) {
Register result = ToRegister(instr->result());
Register array = ToRegister(instr->InputAt(0));
- __ mov(result, FieldOperand(array, FixedArray::kLengthOffset));
-}
-
-
-void LCodeGen::DoExternalArrayLength(LExternalArrayLength* instr) {
- Register result = ToRegister(instr->result());
- Register array = ToRegister(instr->InputAt(0));
- __ mov(result, FieldOperand(array, ExternalArray::kLengthOffset));
+ __ mov(result, FieldOperand(array, FixedArrayBase::kLengthOffset));
}
=======================================
--- /branches/bleeding_edge/src/ia32/lithium-ia32.cc Thu Aug 11 00:22:16
2011
+++ /branches/bleeding_edge/src/ia32/lithium-ia32.cc Thu Aug 11 07:00:16
2011
@@ -1538,16 +1538,10 @@
}
-LInstruction* LChunkBuilder::DoFixedArrayLength(HFixedArrayLength* instr) {
+LInstruction* LChunkBuilder::DoFixedArrayBaseLength(
+ HFixedArrayBaseLength* instr) {
LOperand* array = UseRegisterAtStart(instr->value());
- return DefineAsRegister(new LFixedArrayLength(array));
-}
-
-
-LInstruction* LChunkBuilder::DoExternalArrayLength(
- HExternalArrayLength* instr) {
- LOperand* array = UseRegisterAtStart(instr->value());
- return DefineAsRegister(new LExternalArrayLength(array));
+ return DefineAsRegister(new LFixedArrayBaseLength(array));
}
=======================================
--- /branches/bleeding_edge/src/ia32/lithium-ia32.h Thu Jul 28 06:33:51 2011
+++ /branches/bleeding_edge/src/ia32/lithium-ia32.h Thu Aug 11 07:00:16 2011
@@ -86,8 +86,7 @@
V(DivI) \
V(DoubleToI) \
V(ElementsKind) \
- V(ExternalArrayLength) \
- V(FixedArrayLength) \
+ V(FixedArrayBaseLength) \
V(FunctionLiteral) \
V(GetCachedArrayIndex) \
V(GlobalObject) \
@@ -922,25 +921,15 @@
};
-class LExternalArrayLength: public LTemplateInstruction<1, 1, 0> {
+class LFixedArrayBaseLength: public LTemplateInstruction<1, 1, 0> {
public:
- explicit LExternalArrayLength(LOperand* value) {
+ explicit LFixedArrayBaseLength(LOperand* value) {
inputs_[0] = value;
}
-
DECLARE_CONCRETE_INSTRUCTION(ExternalArrayLength, "external-array-length")
- DECLARE_HYDROGEN_ACCESSOR(ExternalArrayLength)
-};
-
-
-class LFixedArrayLength: public LTemplateInstruction<1, 1, 0> {
- public:
- explicit LFixedArrayLength(LOperand* value) {
- inputs_[0] = value;
- }
-
- DECLARE_CONCRETE_INSTRUCTION(FixedArrayLength, "fixed-array-length")
- DECLARE_HYDROGEN_ACCESSOR(FixedArrayLength)
+ DECLARE_CONCRETE_INSTRUCTION(FixedArrayBaseLength,
+ "fixed-array-base-length")
+ DECLARE_HYDROGEN_ACCESSOR(FixedArrayBaseLength)
};
=======================================
--- /branches/bleeding_edge/src/ia32/stub-cache-ia32.cc Tue Aug 2 06:36:38
2011
+++ /branches/bleeding_edge/src/ia32/stub-cache-ia32.cc Thu Aug 11 07:00:16
2011
@@ -3400,37 +3400,37 @@
__ JumpIfNotSmi(eax, &miss_force_generic);
// Check that the index is in range.
- __ mov(ecx, eax);
- __ SmiUntag(ecx); // Untag the index.
__ mov(ebx, FieldOperand(edx, JSObject::kElementsOffset));
- __ cmp(ecx, FieldOperand(ebx, ExternalArray::kLengthOffset));
+ __ cmp(eax, FieldOperand(ebx, ExternalArray::kLengthOffset));
// Unsigned comparison catches both negative and too-large values.
__ j(above_equal, &miss_force_generic);
__ mov(ebx, FieldOperand(ebx, ExternalArray::kExternalPointerOffset));
// ebx: base pointer of external storage
switch (elements_kind) {
case JSObject::EXTERNAL_BYTE_ELEMENTS:
- __ movsx_b(eax, Operand(ebx, ecx, times_1, 0));
+ __ SmiUntag(eax); // Untag the index.
+ __ movsx_b(eax, Operand(ebx, eax, times_1, 0));
break;
case JSObject::EXTERNAL_UNSIGNED_BYTE_ELEMENTS:
case JSObject::EXTERNAL_PIXEL_ELEMENTS:
- __ movzx_b(eax, Operand(ebx, ecx, times_1, 0));
+ __ SmiUntag(eax); // Untag the index.
+ __ movzx_b(eax, Operand(ebx, eax, times_1, 0));
break;
case JSObject::EXTERNAL_SHORT_ELEMENTS:
- __ movsx_w(eax, Operand(ebx, ecx, times_2, 0));
+ __ movsx_w(eax, Operand(ebx, eax, times_1, 0));
break;
case JSObject::EXTERNAL_UNSIGNED_SHORT_ELEMENTS:
- __ movzx_w(eax, Operand(ebx, ecx, times_2, 0));
+ __ movzx_w(eax, Operand(ebx, eax, times_1, 0));
break;
case JSObject::EXTERNAL_UNSIGNED_INT_ELEMENTS:
case JSObject::EXTERNAL_INT_ELEMENTS:
- __ mov(ecx, Operand(ebx, ecx, times_4, 0));
+ __ mov(ecx, Operand(ebx, eax, times_2, 0));
break;
case JSObject::EXTERNAL_FLOAT_ELEMENTS:
- __ fld_s(Operand(ebx, ecx, times_4, 0));
+ __ fld_s(Operand(ebx, eax, times_2, 0));
break;
case JSObject::EXTERNAL_DOUBLE_ELEMENTS:
- __ fld_d(Operand(ebx, ecx, times_8, 0));
+ __ fld_d(Operand(ebx, eax, times_4, 0));
break;
default:
UNREACHABLE();
@@ -3556,9 +3556,7 @@
// Check that the index is in range.
__ mov(edi, FieldOperand(edx, JSObject::kElementsOffset));
- __ mov(ebx, ecx);
- __ SmiUntag(ebx);
- __ cmp(ebx, FieldOperand(edi, ExternalArray::kLengthOffset));
+ __ cmp(ecx, FieldOperand(edi, ExternalArray::kLengthOffset));
// Unsigned comparison catches both negative and too-large values.
__ j(above_equal, &slow);
@@ -3568,7 +3566,6 @@
// edx: receiver
// ecx: key
// edi: elements array
- // ebx: untagged index
if (elements_kind == JSObject::EXTERNAL_PIXEL_ELEMENTS) {
__ JumpIfNotSmi(eax, &slow);
} else {
@@ -3576,44 +3573,39 @@
}
// smi case
- __ mov(ecx, eax); // Preserve the value in eax. Key is no longer
needed.
- __ SmiUntag(ecx);
+ __ mov(ebx, eax); // Preserve the value in eax as the return value.
+ __ SmiUntag(ebx);
__ mov(edi, FieldOperand(edi, ExternalArray::kExternalPointerOffset));
- // ecx: base pointer of external storage
+ // edi: base pointer of external storage
switch (elements_kind) {
case JSObject::EXTERNAL_PIXEL_ELEMENTS:
- { // Clamp the value to [0..255].
- Label done;
- __ test(ecx, Immediate(0xFFFFFF00));
- __ j(zero, &done, Label::kNear);
- __ setcc(negative, ecx); // 1 if negative, 0 if positive.
- __ dec_b(ecx); // 0 if negative, 255 if positive.
- __ bind(&done);
- }
- __ mov_b(Operand(edi, ebx, times_1, 0), ecx);
+ __ ClampUint8(ebx);
+ __ SmiUntag(ecx);
+ __ mov_b(Operand(edi, ecx, times_1, 0), ebx);
break;
case JSObject::EXTERNAL_BYTE_ELEMENTS:
case JSObject::EXTERNAL_UNSIGNED_BYTE_ELEMENTS:
- __ mov_b(Operand(edi, ebx, times_1, 0), ecx);
+ __ SmiUntag(ecx);
+ __ mov_b(Operand(edi, ecx, times_1, 0), ebx);
break;
case JSObject::EXTERNAL_SHORT_ELEMENTS:
case JSObject::EXTERNAL_UNSIGNED_SHORT_ELEMENTS:
- __ mov_w(Operand(edi, ebx, times_2, 0), ecx);
+ __ mov_w(Operand(edi, ecx, times_1, 0), ebx);
break;
case JSObject::EXTERNAL_INT_ELEMENTS:
case JSObject::EXTERNAL_UNSIGNED_INT_ELEMENTS:
- __ mov(Operand(edi, ebx, times_4, 0), ecx);
+ __ mov(Operand(edi, ecx, times_2, 0), ebx);
break;
case JSObject::EXTERNAL_FLOAT_ELEMENTS:
case JSObject::EXTERNAL_DOUBLE_ELEMENTS:
// Need to perform int-to-float conversion.
- __ push(ecx);
+ __ push(ebx);
__ fild_s(Operand(esp, 0));
- __ pop(ecx);
+ __ pop(ebx);
if (elements_kind == JSObject::EXTERNAL_FLOAT_ELEMENTS) {
- __ fstp_s(Operand(edi, ebx, times_4, 0));
+ __ fstp_s(Operand(edi, ecx, times_2, 0));
} else { // elements_kind == JSObject::EXTERNAL_DOUBLE_ELEMENTS.
- __ fstp_d(Operand(edi, ebx, times_8, 0));
+ __ fstp_d(Operand(edi, ecx, times_4, 0));
}
break;
default:
@@ -3629,7 +3621,6 @@
// edx: receiver
// ecx: key
// edi: elements array
- // ebx: untagged index
__ cmp(FieldOperand(eax, HeapObject::kMapOffset),
Immediate(masm->isolate()->factory()->heap_number_map()));
__ j(not_equal, &slow);
@@ -3638,15 +3629,14 @@
// +/-Infinity into integer arrays basically undefined. For more
// reproducible behavior, convert these to zero.
__ mov(edi, FieldOperand(edi, ExternalArray::kExternalPointerOffset));
- // ebx: untagged index
// edi: base pointer of external storage
if (elements_kind == JSObject::EXTERNAL_FLOAT_ELEMENTS) {
__ fld_d(FieldOperand(eax, HeapNumber::kValueOffset));
- __ fstp_s(Operand(edi, ebx, times_4, 0));
+ __ fstp_s(Operand(edi, ecx, times_2, 0));
__ ret(0);
} else if (elements_kind == JSObject::EXTERNAL_DOUBLE_ELEMENTS) {
__ fld_d(FieldOperand(eax, HeapNumber::kValueOffset));
- __ fstp_d(Operand(edi, ebx, times_8, 0));
+ __ fstp_d(Operand(edi, ecx, times_4, 0));
__ ret(0);
} else {
// Perform float-to-int conversion with truncation (round-to-zero)
@@ -3661,27 +3651,20 @@
elements_kind != JSObject::EXTERNAL_UNSIGNED_INT_ELEMENTS) {
ASSERT(CpuFeatures::IsSupported(SSE2));
CpuFeatures::Scope scope(SSE2);
- __ cvttsd2si(ecx, FieldOperand(eax, HeapNumber::kValueOffset));
+ __ cvttsd2si(ebx, FieldOperand(eax, HeapNumber::kValueOffset));
// ecx: untagged integer value
switch (elements_kind) {
case JSObject::EXTERNAL_PIXEL_ELEMENTS:
- { // Clamp the value to [0..255].
- Label done;
- __ test(ecx, Immediate(0xFFFFFF00));
- __ j(zero, &done, Label::kNear);
- __ setcc(negative, ecx); // 1 if negative, 0 if positive.
- __ dec_b(ecx); // 0 if negative, 255 if positive.
- __ bind(&done);
- }
- __ mov_b(Operand(edi, ebx, times_1, 0), ecx);
- break;
+ __ ClampUint8(ebx);
+ // Fall through.
case JSObject::EXTERNAL_BYTE_ELEMENTS:
case JSObject::EXTERNAL_UNSIGNED_BYTE_ELEMENTS:
- __ mov_b(Operand(edi, ebx, times_1, 0), ecx);
+ __ SmiUntag(ecx);
+ __ mov_b(Operand(edi, ecx, times_1, 0), ebx);
break;
case JSObject::EXTERNAL_SHORT_ELEMENTS:
case JSObject::EXTERNAL_UNSIGNED_SHORT_ELEMENTS:
- __ mov_w(Operand(edi, ebx, times_2, 0), ecx);
+ __ mov_w(Operand(edi, ecx, times_1, 0), ebx);
break;
default:
UNREACHABLE();
@@ -3698,7 +3681,7 @@
__ fld_d(FieldOperand(eax, HeapNumber::kValueOffset));
__ sub(Operand(esp), Immediate(2 * kPointerSize));
__ fisttp_d(Operand(esp, 0));
- __ pop(ecx);
+ __ pop(ebx);
__ add(Operand(esp), Immediate(kPointerSize));
} else {
ASSERT(CpuFeatures::IsSupported(SSE2));
@@ -3709,15 +3692,15 @@
// Note: we could do better for signed int arrays.
__ movd(xmm0, FieldOperand(eax, HeapNumber::kValueOffset));
// We will need the key if we have to make the slow runtime
call.
- __ push(ecx);
- __ LoadPowerOf2(xmm1, ecx, 31);
- __ pop(ecx);
+ __ push(ebx);
+ __ LoadPowerOf2(xmm1, ebx, 31);
+ __ pop(ebx);
__ ucomisd(xmm1, xmm0);
__ j(above_equal, &slow);
- __ cvttsd2si(ecx, Operand(xmm0));
- }
- // ecx: untagged integer value
- __ mov(Operand(edi, ebx, times_4, 0), ecx);
+ __ cvttsd2si(ebx, Operand(xmm0));
+ }
+ // ebx: untagged integer value
+ __ mov(Operand(edi, ecx, times_2, 0), ebx);
}
__ ret(0); // Return original value.
}
=======================================
--- /branches/bleeding_edge/src/mips/stub-cache-mips.cc Wed Aug 3 03:07:34
2011
+++ /branches/bleeding_edge/src/mips/stub-cache-mips.cc Thu Aug 11 07:00:16
2011
@@ -3494,7 +3494,7 @@
__ lw(t1, FieldMemOperand(a3, ExternalArray::kLengthOffset));
__ sra(t2, key, kSmiTagSize);
// Unsigned comparison catches both negative and too-large values.
- __ Branch(&miss_force_generic, Uless, t1, Operand(t2));
+ __ Branch(&miss_force_generic, Ugreater_equal, key, Operand(t1));
__ lw(a3, FieldMemOperand(a3, ExternalArray::kExternalPointerOffset));
// a3: base pointer of external storage
@@ -3822,16 +3822,16 @@
// This stub is meant to be tail-jumped to, the receiver must already
// have been verified by the caller to not be a smi.
- __ lw(a3, FieldMemOperand(receiver, JSObject::kElementsOffset));
-
- // Check that the key is a smi.
+ // Check that the key is a smi.
__ JumpIfNotSmi(key, &miss_force_generic);
+ __ lw(a3, FieldMemOperand(receiver, JSObject::kElementsOffset));
+
// Check that the index is in range.
__ SmiUntag(t0, key);
__ lw(t1, FieldMemOperand(a3, ExternalArray::kLengthOffset));
// Unsigned comparison catches both negative and too-large values.
- __ Branch(&miss_force_generic, Ugreater_equal, t0, Operand(t1));
+ __ Branch(&miss_force_generic, Ugreater_equal, key, Operand(t1));
// Handle both smis and HeapNumbers in the fast path. Go to the
// runtime for all other kinds of values.
=======================================
--- /branches/bleeding_edge/src/objects-inl.h Mon Aug 8 09:14:46 2011
+++ /branches/bleeding_edge/src/objects-inl.h Thu Aug 11 07:00:16 2011
@@ -2114,12 +2114,6 @@
SMI_ACCESSORS(FixedArrayBase, length, kLengthOffset)
-SMI_ACCESSORS(ByteArray, length, kLengthOffset)
-
-// TODO(1493): Investigate if it's possible to s/INT/SMI/ here (and
-// subsequently unify H{Fixed,External}ArrayLength).
-INT_ACCESSORS(ExternalArray, length, kLengthOffset)
-
SMI_ACCESSORS(String, length, kLengthOffset)
=======================================
--- /branches/bleeding_edge/src/objects.h Wed Aug 10 09:05:17 2011
+++ /branches/bleeding_edge/src/objects.h Thu Aug 11 07:00:16 2011
@@ -62,17 +62,8 @@
// - JSMessageObject
// - JSProxy
// - JSFunctionProxy
-// - ByteArray
-// - ExternalArray
-// - ExternalPixelArray
-// - ExternalByteArray
-// - ExternalUnsignedByteArray
-// - ExternalShortArray
-// - ExternalUnsignedShortArray
-// - ExternalIntArray
-// - ExternalUnsignedIntArray
-// - ExternalFloatArray
// - FixedArrayBase
+// - ByteArray
// - FixedArray
// - DescriptorArray
// - HashTable
@@ -85,6 +76,15 @@
// - JSFunctionResultCache
// - SerializedScopeInfo
// - FixedDoubleArray
+// - ExternalArray
+// - ExternalPixelArray
+// - ExternalByteArray
+// - ExternalUnsignedByteArray
+// - ExternalShortArray
+// - ExternalUnsignedShortArray
+// - ExternalIntArray
+// - ExternalUnsignedIntArray
+// - ExternalFloatArray
// - String
// - SeqString
// - SeqAsciiString
@@ -2084,6 +2084,7 @@
static const int kHeaderSize = kLengthOffset + kPointerSize;
};
+
class FixedDoubleArray;
// FixedArray describes fixed-sized arrays with element type Object*.
@@ -3053,12 +3054,8 @@
// ByteArray represents fixed sized byte arrays. Used by the outside
world,
// such as PCRE, and also by the memory allocator and garbage collector to
// fill in free blocks in the heap.
-class ByteArray: public HeapObject {
+class ByteArray: public FixedArrayBase {
public:
- // [length]: length of the array.
- inline int length();
- inline void set_length(int value);
-
// Setter and getter.
inline byte get(int index);
inline void set(int index, byte value);
@@ -3103,10 +3100,6 @@
#endif
// Layout description.
- // Length is smi tagged when it is stored.
- static const int kLengthOffset = HeapObject::kHeaderSize;
- static const int kHeaderSize = kLengthOffset + kPointerSize;
-
static const int kAlignedSize = OBJECT_POINTER_ALIGN(kHeaderSize);
// Maximal memory consumption for a single ByteArray.
@@ -3130,11 +3123,8 @@
// Out-of-range values passed to the setter are converted via a C
// cast, not clamping. Out-of-range indices cause exceptions to be
// raised rather than being silently ignored.
-class ExternalArray: public HeapObject {
+class ExternalArray: public FixedArrayBase {
public:
- // [length]: length of the array.
- inline int length();
- inline void set_length(int value);
inline bool is_the_hole(int index) { return false; }
@@ -3149,9 +3139,8 @@
static const int kMaxLength = 0x3fffffff;
// ExternalArray headers are not quadword aligned.
- static const int kLengthOffset = HeapObject::kHeaderSize;
static const int kExternalPointerOffset =
- POINTER_SIZE_ALIGN(kLengthOffset + kIntSize);
+ POINTER_SIZE_ALIGN(FixedArrayBase::kLengthOffset + kPointerSize);
static const int kHeaderSize = kExternalPointerOffset + kPointerSize;
static const int kAlignedSize = OBJECT_POINTER_ALIGN(kHeaderSize);
=======================================
--- /branches/bleeding_edge/src/x64/lithium-codegen-x64.cc Thu Aug 11
00:22:16 2011
+++ /branches/bleeding_edge/src/x64/lithium-codegen-x64.cc Thu Aug 11
07:00:16 2011
@@ -1216,17 +1216,10 @@
}
-void LCodeGen::DoFixedArrayLength(LFixedArrayLength* instr) {
+void LCodeGen::DoFixedArrayBaseLength(LFixedArrayBaseLength* instr) {
Register result = ToRegister(instr->result());
Register array = ToRegister(instr->InputAt(0));
- __ movq(result, FieldOperand(array, FixedArray::kLengthOffset));
-}
-
-
-void LCodeGen::DoExternalArrayLength(LExternalArrayLength* instr) {
- Register result = ToRegister(instr->result());
- Register array = ToRegister(instr->InputAt(0));
- __ movl(result, FieldOperand(array, ExternalPixelArray::kLengthOffset));
+ __ movq(result, FieldOperand(array, FixedArrayBase::kLengthOffset));
}
=======================================
--- /branches/bleeding_edge/src/x64/lithium-x64.cc Thu Aug 11 00:22:16 2011
+++ /branches/bleeding_edge/src/x64/lithium-x64.cc Thu Aug 11 07:00:16 2011
@@ -1498,16 +1498,10 @@
}
-LInstruction* LChunkBuilder::DoFixedArrayLength(HFixedArrayLength* instr) {
+LInstruction* LChunkBuilder::DoFixedArrayBaseLength(
+ HFixedArrayBaseLength* instr) {
LOperand* array = UseRegisterAtStart(instr->value());
- return DefineAsRegister(new LFixedArrayLength(array));
-}
-
-
-LInstruction* LChunkBuilder::DoExternalArrayLength(
- HExternalArrayLength* instr) {
- LOperand* array = UseRegisterAtStart(instr->value());
- return DefineAsRegister(new LExternalArrayLength(array));
+ return DefineAsRegister(new LFixedArrayBaseLength(array));
}
=======================================
--- /branches/bleeding_edge/src/x64/lithium-x64.h Tue Jul 19 06:04:00 2011
+++ /branches/bleeding_edge/src/x64/lithium-x64.h Thu Aug 11 07:00:16 2011
@@ -92,8 +92,7 @@
V(DivI) \
V(DoubleToI) \
V(ElementsKind) \
- V(ExternalArrayLength) \
- V(FixedArrayLength) \
+ V(FixedArrayBaseLength) \
V(FunctionLiteral) \
V(GetCachedArrayIndex) \
V(GlobalObject) \
@@ -913,25 +912,15 @@
};
-class LExternalArrayLength: public LTemplateInstruction<1, 1, 0> {
+class LFixedArrayBaseLength: public LTemplateInstruction<1, 1, 0> {
public:
- explicit LExternalArrayLength(LOperand* value) {
+ explicit LFixedArrayBaseLength(LOperand* value) {
inputs_[0] = value;
}
-
DECLARE_CONCRETE_INSTRUCTION(ExternalArrayLength, "external-array-length")
- DECLARE_HYDROGEN_ACCESSOR(ExternalArrayLength)
-};
-
-
-class LFixedArrayLength: public LTemplateInstruction<1, 1, 0> {
- public:
- explicit LFixedArrayLength(LOperand* value) {
- inputs_[0] = value;
- }
-
- DECLARE_CONCRETE_INSTRUCTION(FixedArrayLength, "fixed-array-length")
- DECLARE_HYDROGEN_ACCESSOR(FixedArrayLength)
+ DECLARE_CONCRETE_INSTRUCTION(FixedArrayBaseLength,
+ "fixed-array-base-length")
+ DECLARE_HYDROGEN_ACCESSOR(FixedArrayBaseLength)
};
=======================================
--- /branches/bleeding_edge/src/x64/stub-cache-x64.cc Tue Aug 2 06:36:38
2011
+++ /branches/bleeding_edge/src/x64/stub-cache-x64.cc Thu Aug 11 07:00:16
2011
@@ -3243,8 +3243,7 @@
// Check that the index is in range.
__ movq(rbx, FieldOperand(rdx, JSObject::kElementsOffset));
- __ SmiToInteger32(rcx, rax);
- __ cmpl(rcx, FieldOperand(rbx, ExternalArray::kLengthOffset));
+ __ cmpl(rax, FieldOperand(rbx, ExternalArray::kLengthOffset));
// Unsigned comparison catches both negative and too-large values.
__ j(above_equal, &miss_force_generic);
@@ -3256,29 +3255,31 @@
// rbx: base pointer of external storage
switch (elements_kind) {
case JSObject::EXTERNAL_BYTE_ELEMENTS:
+ __ SmiToInteger32(rcx, rax);
__ movsxbq(rcx, Operand(rbx, rcx, times_1, 0));
break;
case JSObject::EXTERNAL_PIXEL_ELEMENTS:
case JSObject::EXTERNAL_UNSIGNED_BYTE_ELEMENTS:
+ __ SmiToInteger32(rcx, rax);
__ movzxbq(rcx, Operand(rbx, rcx, times_1, 0));
break;
case JSObject::EXTERNAL_SHORT_ELEMENTS:
- __ movsxwq(rcx, Operand(rbx, rcx, times_2, 0));
+ __ movsxwq(rcx, Operand(rbx, rax, times_1, 0));
break;
case JSObject::EXTERNAL_UNSIGNED_SHORT_ELEMENTS:
- __ movzxwq(rcx, Operand(rbx, rcx, times_2, 0));
+ __ movzxwq(rcx, Operand(rbx, rax, times_1, 0));
break;
case JSObject::EXTERNAL_INT_ELEMENTS:
- __ movsxlq(rcx, Operand(rbx, rcx, times_4, 0));
+ __ movsxlq(rcx, Operand(rbx, rax, times_2, 0));
break;
case JSObject::EXTERNAL_UNSIGNED_INT_ELEMENTS:
- __ movl(rcx, Operand(rbx, rcx, times_4, 0));
+ __ movl(rcx, Operand(rbx, rax, times_2, 0));
break;
case JSObject::EXTERNAL_FLOAT_ELEMENTS:
- __ cvtss2sd(xmm0, Operand(rbx, rcx, times_4, 0));
+ __ cvtss2sd(xmm0, Operand(rbx, rax, times_2, 0));
break;
case JSObject::EXTERNAL_DOUBLE_ELEMENTS:
- __ movsd(xmm0, Operand(rbx, rcx, times_8, 0));
+ __ movsd(xmm0, Operand(rbx, rax, times_4, 0));
break;
default:
UNREACHABLE();
@@ -3378,8 +3379,7 @@
// Check that the index is in range.
__ movq(rbx, FieldOperand(rdx, JSObject::kElementsOffset));
- __ SmiToInteger32(rdi, rcx); // Untag the index.
- __ cmpl(rdi, FieldOperand(rbx, ExternalArray::kLengthOffset));
+ __ cmpl(rcx, FieldOperand(rbx, ExternalArray::kLengthOffset));
// Unsigned comparison catches both negative and too-large values.
__ j(above_equal, &miss_force_generic);
@@ -3389,7 +3389,6 @@
// rcx: key (a smi)
// rdx: receiver (a JSObject)
// rbx: elements array
- // rdi: untagged key
Label check_heap_number;
if (elements_kind == JSObject::EXTERNAL_PIXEL_ELEMENTS) {
// Float to pixel conversion is only implemented in the runtime for
now.
@@ -3403,37 +3402,32 @@
// rbx: base pointer of external storage
switch (elements_kind) {
case JSObject::EXTERNAL_PIXEL_ELEMENTS:
- { // Clamp the value to [0..255].
- Label done;
- __ testl(rdx, Immediate(0xFFFFFF00));
- __ j(zero, &done, Label::kNear);
- __ setcc(negative, rdx); // 1 if negative, 0 if positive.
- __ decb(rdx); // 0 if negative, 255 if positive.
- __ bind(&done);
- }
+ __ ClampUint8(rdx);
+ __ SmiToInteger32(rdi, rcx);
__ movb(Operand(rbx, rdi, times_1, 0), rdx);
break;
case JSObject::EXTERNAL_BYTE_ELEMENTS:
case JSObject::EXTERNAL_UNSIGNED_BYTE_ELEMENTS:
+ __ SmiToInteger32(rdi, rcx);
__ movb(Operand(rbx, rdi, times_1, 0), rdx);
break;
case JSObject::EXTERNAL_SHORT_ELEMENTS:
case JSObject::EXTERNAL_UNSIGNED_SHORT_ELEMENTS:
- __ movw(Operand(rbx, rdi, times_2, 0), rdx);
+ __ movw(Operand(rbx, rcx, times_1, 0), rdx);
break;
case JSObject::EXTERNAL_INT_ELEMENTS:
case JSObject::EXTERNAL_UNSIGNED_INT_ELEMENTS:
- __ movl(Operand(rbx, rdi, times_4, 0), rdx);
+ __ movl(Operand(rbx, rcx, times_2, 0), rdx);
break;
case JSObject::EXTERNAL_FLOAT_ELEMENTS:
// Need to perform int-to-float conversion.
__ cvtlsi2ss(xmm0, rdx);
- __ movss(Operand(rbx, rdi, times_4, 0), xmm0);
+ __ movss(Operand(rbx, rcx, times_2, 0), xmm0);
break;
case JSObject::EXTERNAL_DOUBLE_ELEMENTS:
// Need to perform int-to-float conversion.
__ cvtlsi2sd(xmm0, rdx);
- __ movsd(Operand(rbx, rdi, times_8, 0), xmm0);
+ __ movsd(Operand(rbx, rcx, times_4, 0), xmm0);
break;
case JSObject::FAST_ELEMENTS:
case JSObject::FAST_DOUBLE_ELEMENTS:
@@ -3451,7 +3445,6 @@
// rcx: key (a smi)
// rdx: receiver (a JSObject)
// rbx: elements array
- // rdi: untagged key
__ CmpObjectType(rax, HEAP_NUMBER_TYPE, kScratchRegister);
__ j(not_equal, &slow);
// No more branches to slow case on this path.
@@ -3461,15 +3454,15 @@
// reproducible behavior, convert these to zero.
__ movsd(xmm0, FieldOperand(rax, HeapNumber::kValueOffset));
__ movq(rbx, FieldOperand(rbx, ExternalArray::kExternalPointerOffset));
- // rdi: untagged index
// rbx: base pointer of external storage
+ // rcx: key
// top of FPU stack: value
if (elements_kind == JSObject::EXTERNAL_FLOAT_ELEMENTS) {
__ cvtsd2ss(xmm0, xmm0);
- __ movss(Operand(rbx, rdi, times_4, 0), xmm0);
+ __ movss(Operand(rbx, rcx, times_2, 0), xmm0);
__ ret(0);
} else if (elements_kind == JSObject::EXTERNAL_DOUBLE_ELEMENTS) {
- __ movsd(Operand(rbx, rdi, times_8, 0), xmm0);
+ __ movsd(Operand(rbx, rcx, times_4, 0), xmm0);
__ ret(0);
} else {
// Perform float-to-int conversion with truncation (round-to-zero)
@@ -3482,24 +3475,31 @@
// rdi: untagged index
// rbx: base pointer of external storage
switch (elements_kind) {
+ case JSObject::EXTERNAL_PIXEL_ELEMENTS:
+ __ ClampUint8(rdx);
+ __ cvttsd2si(rdx, xmm0);
+ __ SmiToInteger32(rdi, rcx);
+ __ movb(Operand(rbx, rdi, times_1, 0), rdx);
+ break;
case JSObject::EXTERNAL_BYTE_ELEMENTS:
case JSObject::EXTERNAL_UNSIGNED_BYTE_ELEMENTS:
__ cvttsd2si(rdx, xmm0);
+ __ SmiToInteger32(rdi, rcx);
__ movb(Operand(rbx, rdi, times_1, 0), rdx);
break;
case JSObject::EXTERNAL_SHORT_ELEMENTS:
case JSObject::EXTERNAL_UNSIGNED_SHORT_ELEMENTS:
__ cvttsd2si(rdx, xmm0);
- __ movw(Operand(rbx, rdi, times_2, 0), rdx);
+ __ SmiToInteger32(rdi, rcx);
+ __ movw(Operand(rbx, rcx, times_1, 0), rdx);
break;
case JSObject::EXTERNAL_INT_ELEMENTS:
case JSObject::EXTERNAL_UNSIGNED_INT_ELEMENTS:
// Convert to int64, so that NaN and infinities become
// 0x8000000000000000, which is zero mod 2^32.
__ cvttsd2siq(rdx, xmm0);
- __ movl(Operand(rbx, rdi, times_4, 0), rdx);
+ __ movl(Operand(rbx, rcx, times_2, 0), rdx);
break;
- case JSObject::EXTERNAL_PIXEL_ELEMENTS:
case JSObject::EXTERNAL_FLOAT_ELEMENTS:
case JSObject::EXTERNAL_DOUBLE_ELEMENTS:
case JSObject::FAST_ELEMENTS:
=======================================
--- /branches/bleeding_edge/test/mjsunit/external-array.js Thu May 26
05:07:22 2011
+++ /branches/bleeding_edge/test/mjsunit/external-array.js Thu Aug 11
07:00:16 2011
@@ -189,10 +189,20 @@
%DeoptimizeFunction(test_func);
gc(); // Makes V8 forget about type information for test_func.
}
+
+function run_bounds_test(test_func, array, expected_result) {
+ assertEquals(undefined, a[kElementCount]);
+ a[kElementCount] = 456;
+ assertEquals(undefined, a[kElementCount]);
+ assertEquals(undefined, a[kElementCount+1]);
+ a[kElementCount+1] = 456;
+ assertEquals(undefined, a[kElementCount+1]);
+}
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;
}
@@ -220,6 +230,16 @@
assertTrue(delete a.length);
a.length = 2;
assertEquals(2, a.length);
+
+ // Make sure bounds checks are handled correctly for external arrays.
+ run_bounds_test(a);
+ run_bounds_test(a);
+ run_bounds_test(a);
+ %OptimizeFunctionOnNextCall(run_bounds_test);
+ run_bounds_test(a);
+ %DeoptimizeFunction(run_bounds_test);
+ gc(); // Makes V8 forget about type information for test_func.
+
}
function array_load_set_smi_check(a) {
--
v8-dev mailing list
[email protected]
http://groups.google.com/group/v8-dev