summaryrefslogtreecommitdiff
path: root/deps/v8/src/ia32/ic-ia32.cc
diff options
context:
space:
mode:
Diffstat (limited to 'deps/v8/src/ia32/ic-ia32.cc')
-rw-r--r--deps/v8/src/ia32/ic-ia32.cc103
1 files changed, 36 insertions, 67 deletions
diff --git a/deps/v8/src/ia32/ic-ia32.cc b/deps/v8/src/ia32/ic-ia32.cc
index 644d20072..2ba64dcae 100644
--- a/deps/v8/src/ia32/ic-ia32.cc
+++ b/deps/v8/src/ia32/ic-ia32.cc
@@ -304,7 +304,7 @@ void KeyedLoadIC::GenerateGeneric(MacroAssembler* masm) {
// -- edx : receiver
// -- esp[0] : return address
// -----------------------------------
- Label slow, check_string, index_int, index_string;
+ Label slow, check_string, index_smi, index_string;
Label check_pixel_array, probe_dictionary;
Label check_number_dictionary;
@@ -329,18 +329,17 @@ void KeyedLoadIC::GenerateGeneric(MacroAssembler* masm) {
// Check that the key is a smi.
__ test(eax, Immediate(kSmiTagMask));
__ j(not_zero, &check_string, not_taken);
- __ mov(ebx, eax);
- __ SmiUntag(ebx);
// Get the elements array of the object.
- __ bind(&index_int);
+ __ bind(&index_smi);
__ mov(ecx, FieldOperand(edx, JSObject::kElementsOffset));
// Check that the object is in fast mode (not dictionary).
__ CheckMap(ecx, Factory::fixed_array_map(), &check_pixel_array, true);
// Check that the key (index) is within bounds.
- __ cmp(ebx, FieldOperand(ecx, FixedArray::kLengthOffset));
+ __ cmp(eax, FieldOperand(ecx, FixedArray::kLengthOffset));
__ j(above_equal, &slow);
// Fast case: Do the load.
- __ mov(ecx, FieldOperand(ecx, ebx, times_4, FixedArray::kHeaderSize));
+ ASSERT((kPointerSize == 4) && (kSmiTagSize == 1) && (kSmiTag == 0));
+ __ mov(ecx, FieldOperand(ecx, eax, times_2, FixedArray::kHeaderSize));
__ cmp(Operand(ecx), Immediate(Factory::the_hole_value()));
// In case the loaded value is the_hole we have to consult GetProperty
// to ensure the prototype chain is searched.
@@ -352,9 +351,10 @@ void KeyedLoadIC::GenerateGeneric(MacroAssembler* masm) {
__ bind(&check_pixel_array);
// Check whether the elements is a pixel array.
// edx: receiver
- // ebx: untagged index
// eax: key
// ecx: elements
+ __ mov(ebx, eax);
+ __ SmiUntag(ebx);
__ CheckMap(ecx, Factory::pixel_array_map(), &check_number_dictionary, true);
__ cmp(ebx, FieldOperand(ecx, PixelArray::kLengthOffset));
__ j(above_equal, &slow);
@@ -485,9 +485,13 @@ void KeyedLoadIC::GenerateGeneric(MacroAssembler* masm) {
ASSERT(TenToThe(String::kMaxCachedArrayIndexLength) <
(1 << String::kArrayIndexValueBits));
__ bind(&index_string);
- __ and_(ebx, String::kArrayIndexHashMask);
- __ shr(ebx, String::kHashShift);
- __ jmp(&index_int);
+ // We want the smi-tagged index in eax. kArrayIndexValueMask has zeros in
+ // the low kHashShift bits.
+ ASSERT(String::kHashShift >= kSmiTagSize);
+ __ and_(ebx, String::kArrayIndexValueMask);
+ __ shr(ebx, String::kHashShift - kSmiTagSize);
+ __ mov(eax, ebx);
+ __ jmp(&index_smi);
}
@@ -498,60 +502,29 @@ void KeyedLoadIC::GenerateString(MacroAssembler* masm) {
// -- esp[0] : return address
// -----------------------------------
Label miss;
- Label index_not_smi;
Label index_out_of_range;
- Label slow_char_code;
- Label got_char_code;
Register receiver = edx;
Register index = eax;
- Register code = ebx;
- Register scratch = ecx;
-
- StringHelper::GenerateFastCharCodeAt(masm,
- receiver,
- index,
- scratch,
- code,
- &miss, // When not a string.
- &index_not_smi,
- &index_out_of_range,
- &slow_char_code);
- // If we didn't bail out, code register contains smi tagged char
- // code.
- __ bind(&got_char_code);
- StringHelper::GenerateCharFromCode(masm, code, eax, JUMP_FUNCTION);
-#ifdef DEBUG
- __ Abort("Unexpected fall-through from char from code tail call");
-#endif
-
- // Check if key is a heap number.
- __ bind(&index_not_smi);
- __ CheckMap(index, Factory::heap_number_map(), &miss, true);
-
- // Push receiver and key on the stack (now that we know they are a
- // string and a number), and call runtime.
- __ bind(&slow_char_code);
- __ EnterInternalFrame();
- __ push(receiver);
- __ push(index);
- __ CallRuntime(Runtime::kStringCharCodeAt, 2);
- ASSERT(!code.is(eax));
- __ mov(code, eax);
- __ LeaveInternalFrame();
+ Register scratch1 = ebx;
+ Register scratch2 = ecx;
+ Register result = eax;
+
+ StringCharAtGenerator char_at_generator(receiver,
+ index,
+ scratch1,
+ scratch2,
+ result,
+ &miss, // When not a string.
+ &miss, // When not a number.
+ &index_out_of_range,
+ STRING_INDEX_IS_ARRAY_INDEX);
+ char_at_generator.GenerateFast(masm);
+ __ ret(0);
+
+ ICRuntimeCallHelper call_helper;
+ char_at_generator.GenerateSlow(masm, call_helper);
- // Check if the runtime call returned NaN char code. If yes, return
- // undefined. Otherwise, we can continue.
- if (FLAG_debug_code) {
- ASSERT(kSmiTag == 0);
- __ test(code, Immediate(kSmiTagMask));
- __ j(zero, &got_char_code);
- __ mov(scratch, FieldOperand(code, HeapObject::kMapOffset));
- __ cmp(scratch, Factory::heap_number_map());
- __ Assert(equal, "StringCharCodeAt must return smi or heap number");
- }
- __ cmp(code, Factory::nan_value());
- __ j(not_equal, &got_char_code);
__ bind(&index_out_of_range);
__ Set(eax, Immediate(Factory::undefined_value()));
__ ret(0);
@@ -792,9 +765,7 @@ void KeyedStoreIC::GenerateGeneric(MacroAssembler* masm) {
__ mov(edi, FieldOperand(edx, JSObject::kElementsOffset));
// Check that the object is in fast mode (not dictionary).
__ CheckMap(edi, Factory::fixed_array_map(), &check_pixel_array, true);
- __ mov(ebx, Operand(ecx));
- __ SmiUntag(ebx);
- __ cmp(ebx, FieldOperand(edi, Array::kLengthOffset));
+ __ cmp(ecx, FieldOperand(edi, FixedArray::kLengthOffset));
__ j(below, &fast, taken);
// Slow case: call runtime.
@@ -804,7 +775,7 @@ void KeyedStoreIC::GenerateGeneric(MacroAssembler* masm) {
// Check whether the elements is a pixel array.
__ bind(&check_pixel_array);
// eax: value
- // ecx: key
+ // ecx: key (a smi)
// edx: receiver
// edi: elements array
__ CheckMap(edi, Factory::pixel_array_map(), &slow, true);
@@ -840,13 +811,11 @@ void KeyedStoreIC::GenerateGeneric(MacroAssembler* masm) {
// edi: receiver->elements, a FixedArray
// flags: compare (ecx, edx.length())
__ j(not_equal, &slow, not_taken); // do not leave holes in the array
- __ mov(ebx, ecx);
- __ SmiUntag(ebx); // untag
- __ cmp(ebx, FieldOperand(edi, Array::kLengthOffset));
+ __ cmp(ecx, FieldOperand(edi, FixedArray::kLengthOffset));
__ j(above_equal, &slow, not_taken);
// Add 1 to receiver->length, and go to fast array write.
__ add(FieldOperand(edx, JSArray::kLengthOffset),
- Immediate(1 << kSmiTagSize));
+ Immediate(Smi::FromInt(1)));
__ jmp(&fast);
// Array case: Get the length and the elements array from the JS