diff options
Diffstat (limited to 'deps/v8/src/ia32/ic-ia32.cc')
-rw-r--r-- | deps/v8/src/ia32/ic-ia32.cc | 103 |
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 |