| Index: src/arm/ic-arm.cc
|
| diff --git a/src/arm/ic-arm.cc b/src/arm/ic-arm.cc
|
| index c308d69df5d558777ae6e900cefbcda8f8bc8631..ba2e677a781fe5db3a8d2a02249ec8dba6580379 100644
|
| --- a/src/arm/ic-arm.cc
|
| +++ b/src/arm/ic-arm.cc
|
| @@ -161,11 +161,11 @@ static void GenerateNumberDictionaryLoad(MacroAssembler* masm,
|
| //
|
| // key - holds the smi key on entry and is unchanged if a branch is
|
| // performed to the miss label.
|
| + // Holds the result on exit if the load succeeded.
|
| //
|
| // Scratch registers:
|
| //
|
| // t0 - holds the untagged key on entry and holds the hash once computed.
|
| - // Holds the result on exit if the load succeeded.
|
| //
|
| // t1 - used to hold the capacity mask of the dictionary
|
| //
|
| @@ -233,7 +233,7 @@ static void GenerateNumberDictionaryLoad(MacroAssembler* masm,
|
| // Get the value at the masked, scaled index and return.
|
| const int kValueOffset =
|
| NumberDictionary::kElementsStartOffset + kPointerSize;
|
| - __ ldr(t0, FieldMemOperand(t2, kValueOffset));
|
| + __ ldr(key, FieldMemOperand(t2, kValueOffset));
|
| }
|
|
|
|
|
| @@ -739,9 +739,6 @@ void KeyedLoadIC::GenerateGeneric(MacroAssembler* masm) {
|
|
|
| // Check that the key is a smi.
|
| __ BranchOnNotSmi(key, &slow);
|
| - // Untag key into r2..
|
| - __ mov(r2, Operand(key, ASR, kSmiTagSize));
|
| -
|
| // Get the elements array of the object.
|
| __ ldr(r4, FieldMemOperand(receiver, JSObject::kElementsOffset));
|
| // Check that the object is in fast mode (not dictionary).
|
| @@ -750,12 +747,14 @@ void KeyedLoadIC::GenerateGeneric(MacroAssembler* masm) {
|
| __ cmp(r3, ip);
|
| __ b(ne, &check_pixel_array);
|
| // Check that the key (index) is within bounds.
|
| - __ ldr(r3, FieldMemOperand(r4, Array::kLengthOffset));
|
| - __ cmp(r2, r3);
|
| + __ ldr(r3, FieldMemOperand(r4, FixedArray::kLengthOffset));
|
| + __ cmp(key, Operand(r3));
|
| __ b(hs, &slow);
|
| // Fast case: Do the load.
|
| __ add(r3, r4, Operand(FixedArray::kHeaderSize - kHeapObjectTag));
|
| - __ ldr(r2, MemOperand(r3, r2, LSL, kPointerSizeLog2));
|
| + // The key is a smi.
|
| + ASSERT(kSmiTag == 0 && kSmiTagSize < kPointerSizeLog2);
|
| + __ ldr(r2, MemOperand(r3, key, LSL, kPointerSizeLog2 - kSmiTagSize));
|
| __ LoadRoot(ip, Heap::kTheHoleValueRootIndex);
|
| __ cmp(r2, ip);
|
| // In case the loaded value is the_hole we have to consult GetProperty
|
| @@ -766,7 +765,6 @@ void KeyedLoadIC::GenerateGeneric(MacroAssembler* masm) {
|
|
|
| // Check whether the elements is a pixel array.
|
| // r0: key
|
| - // r2: untagged index
|
| // r3: elements map
|
| // r4: elements
|
| __ bind(&check_pixel_array);
|
| @@ -774,6 +772,7 @@ void KeyedLoadIC::GenerateGeneric(MacroAssembler* masm) {
|
| __ cmp(r3, ip);
|
| __ b(ne, &check_number_dictionary);
|
| __ ldr(ip, FieldMemOperand(r4, PixelArray::kLengthOffset));
|
| + __ mov(r2, Operand(key, ASR, kSmiTagSize));
|
| __ cmp(r2, ip);
|
| __ b(hs, &slow);
|
| __ ldr(ip, FieldMemOperand(r4, PixelArray::kExternalPointerOffset));
|
| @@ -784,14 +783,13 @@ void KeyedLoadIC::GenerateGeneric(MacroAssembler* masm) {
|
| __ bind(&check_number_dictionary);
|
| // Check whether the elements is a number dictionary.
|
| // r0: key
|
| - // r2: untagged index
|
| // r3: elements map
|
| // r4: elements
|
| __ LoadRoot(ip, Heap::kHashTableMapRootIndex);
|
| __ cmp(r3, ip);
|
| __ b(ne, &slow);
|
| + __ mov(r2, Operand(r0, ASR, kSmiTagSize));
|
| GenerateNumberDictionaryLoad(masm, &slow, r4, r0, r2, r3, r5);
|
| - __ mov(r0, r2);
|
| __ Ret();
|
|
|
| // Slow case, key and receiver still in r0 and r1.
|
| @@ -1275,11 +1273,12 @@ void KeyedStoreIC::GenerateGeneric(MacroAssembler* masm) {
|
| __ LoadRoot(ip, Heap::kFixedArrayMapRootIndex);
|
| __ cmp(r2, ip);
|
| __ b(ne, &check_pixel_array);
|
| - // Untag the key (for checking against untagged length in the fixed array).
|
| - __ mov(r1, Operand(r1, ASR, kSmiTagSize));
|
| // Compute address to store into and check array bounds.
|
| __ add(r2, r3, Operand(FixedArray::kHeaderSize - kHeapObjectTag));
|
| - __ add(r2, r2, Operand(r1, LSL, kPointerSizeLog2));
|
| + // The key is a smi. Assert we can shift left by 1 to use it as a
|
| + // byte offset.
|
| + ASSERT(kSmiTag == 0 && kSmiTagSize < kPointerSizeLog2);
|
| + __ add(r2, r2, Operand(r1, LSL, kPointerSizeLog2 - kSmiTagSize));
|
| __ ldr(ip, FieldMemOperand(r3, FixedArray::kLengthOffset));
|
| __ cmp(r1, Operand(ip));
|
| __ b(lo, &fast);
|
| @@ -1326,12 +1325,11 @@ void KeyedStoreIC::GenerateGeneric(MacroAssembler* masm) {
|
| // r0 == value, r1 == key, r2 == elements, r3 == object
|
| __ bind(&extra);
|
| __ b(ne, &slow); // do not leave holes in the array
|
| - __ mov(r1, Operand(r1, ASR, kSmiTagSize)); // untag
|
| - __ ldr(ip, FieldMemOperand(r2, Array::kLengthOffset));
|
| + __ ldr(ip, FieldMemOperand(r2, FixedArray::kLengthOffset));
|
| __ cmp(r1, Operand(ip));
|
| __ b(hs, &slow);
|
| - __ mov(r1, Operand(r1, LSL, kSmiTagSize)); // restore tag
|
| - __ add(r1, r1, Operand(1 << kSmiTagSize)); // and increment
|
| + // Increment the key to get the new length.
|
| + __ add(r1, r1, Operand(Smi::FromInt(1)));
|
| __ str(r1, FieldMemOperand(r3, JSArray::kLengthOffset));
|
| __ mov(r3, Operand(r2));
|
| // NOTE: Computing the address to store into must take the fact
|
| @@ -1339,6 +1337,9 @@ void KeyedStoreIC::GenerateGeneric(MacroAssembler* masm) {
|
| int displacement = FixedArray::kHeaderSize - kHeapObjectTag -
|
| ((1 << kSmiTagSize) * 2);
|
| __ add(r2, r2, Operand(displacement));
|
| + // The key is a smi. Assert we can shift left by 1 to use it as a
|
| + // byte offset.
|
| + ASSERT(kSmiTag == 0 && kSmiTagSize < kPointerSizeLog2);
|
| __ add(r2, r2, Operand(r1, LSL, kPointerSizeLog2 - kSmiTagSize));
|
| __ b(&fast);
|
|
|
| @@ -1363,6 +1364,9 @@ void KeyedStoreIC::GenerateGeneric(MacroAssembler* masm) {
|
| __ b(hs, &extra);
|
| __ mov(r3, Operand(r2));
|
| __ add(r2, r2, Operand(FixedArray::kHeaderSize - kHeapObjectTag));
|
| + // The key is a smi. Assert we can shift left by 1 to use it as a
|
| + // byte offset.
|
| + ASSERT(kSmiTag == 0 && kSmiTagSize < kPointerSizeLog2);
|
| __ add(r2, r2, Operand(r1, LSL, kPointerSizeLog2 - kSmiTagSize));
|
|
|
|
|
|
|