diff options
author | Ryan Dahl <ry@tinyclouds.org> | 2010-03-10 10:50:46 -0800 |
---|---|---|
committer | Ryan Dahl <ry@tinyclouds.org> | 2010-03-10 10:50:46 -0800 |
commit | 073947c150316cfc0bd440851e590663c3b67814 (patch) | |
tree | 892fc64c0d5cdfd021c14af01a631f6b6c91b982 /deps/v8/src/ia32/ic-ia32.cc | |
parent | c2c0cfb75f46ddcb3a0900f244966764d2640240 (diff) | |
download | node-new-073947c150316cfc0bd440851e590663c3b67814.tar.gz |
Upgrade V8 to 2.1.3
Diffstat (limited to 'deps/v8/src/ia32/ic-ia32.cc')
-rw-r--r-- | deps/v8/src/ia32/ic-ia32.cc | 279 |
1 files changed, 131 insertions, 148 deletions
diff --git a/deps/v8/src/ia32/ic-ia32.cc b/deps/v8/src/ia32/ic-ia32.cc index fcc82710b6..555cd1bf9b 100644 --- a/deps/v8/src/ia32/ic-ia32.cc +++ b/deps/v8/src/ia32/ic-ia32.cc @@ -610,8 +610,9 @@ void KeyedLoadIC::GenerateIndexedInterceptor(MacroAssembler* masm) { __ push(ecx); // return address // Perform tail call to the entry. - __ TailCallRuntime(ExternalReference( - IC_Utility(kKeyedLoadPropertyWithInterceptor)), 2, 1); + ExternalReference ref = ExternalReference( + IC_Utility(kKeyedLoadPropertyWithInterceptor)); + __ TailCallExternalReference(ref, 2, 1); __ bind(&slow); GenerateMiss(masm); @@ -621,54 +622,41 @@ void KeyedLoadIC::GenerateIndexedInterceptor(MacroAssembler* masm) { void KeyedStoreIC::GenerateGeneric(MacroAssembler* masm) { // ----------- S t a t e ------------- // -- eax : value + // -- ecx : key + // -- edx : receiver // -- esp[0] : return address - // -- esp[4] : key - // -- esp[8] : receiver // ----------------------------------- Label slow, fast, array, extra, check_pixel_array; - // Get the receiver from the stack. - __ mov(edx, Operand(esp, 2 * kPointerSize)); // 2 ~ return address, key // Check that the object isn't a smi. __ test(edx, Immediate(kSmiTagMask)); __ j(zero, &slow, not_taken); // Get the map from the receiver. - __ mov(ecx, FieldOperand(edx, HeapObject::kMapOffset)); + __ mov(edi, FieldOperand(edx, HeapObject::kMapOffset)); // Check that the receiver does not require access checks. We need // to do this because this generic stub does not perform map checks. - __ movzx_b(ebx, FieldOperand(ecx, Map::kBitFieldOffset)); + __ movzx_b(ebx, FieldOperand(edi, Map::kBitFieldOffset)); __ test(ebx, Immediate(1 << Map::kIsAccessCheckNeeded)); __ j(not_zero, &slow, not_taken); - // Get the key from the stack. - __ mov(ebx, Operand(esp, 1 * kPointerSize)); // 1 ~ return address // Check that the key is a smi. - __ test(ebx, Immediate(kSmiTagMask)); + __ test(ecx, Immediate(kSmiTagMask)); __ j(not_zero, &slow, not_taken); - // Get the instance type from the map of the receiver. - __ movzx_b(ecx, FieldOperand(ecx, Map::kInstanceTypeOffset)); - // Check if the object is a JS array or not. - __ cmp(ecx, JS_ARRAY_TYPE); + __ CmpInstanceType(edi, JS_ARRAY_TYPE); __ j(equal, &array); // Check that the object is some kind of JS object. - __ cmp(ecx, FIRST_JS_OBJECT_TYPE); - __ j(less, &slow, not_taken); + __ CmpInstanceType(edi, FIRST_JS_OBJECT_TYPE); + __ j(below, &slow, not_taken); // Object case: Check key against length in the elements array. // eax: value // edx: JSObject - // ebx: index (as a smi) - __ mov(ecx, FieldOperand(edx, JSObject::kElementsOffset)); + // ecx: key (a smi) + __ mov(edi, FieldOperand(edx, JSObject::kElementsOffset)); // Check that the object is in fast mode (not dictionary). - __ cmp(FieldOperand(ecx, HeapObject::kMapOffset), - Immediate(Factory::fixed_array_map())); - __ j(not_equal, &check_pixel_array, not_taken); - // Untag the key (for checking against untagged length in the fixed array). - __ mov(edx, Operand(ebx)); - __ sar(edx, kSmiTagSize); // untag the index and use it for the comparison - __ cmp(edx, FieldOperand(ecx, Array::kLengthOffset)); - // eax: value - // ecx: FixedArray - // ebx: index (as a smi) + __ CheckMap(edi, Factory::fixed_array_map(), &check_pixel_array, true); + __ mov(ebx, Operand(ecx)); + __ SmiUntag(ebx); + __ cmp(ebx, FieldOperand(edi, Array::kLengthOffset)); __ j(below, &fast, taken); // Slow case: call runtime. @@ -676,52 +664,51 @@ void KeyedStoreIC::GenerateGeneric(MacroAssembler* masm) { GenerateRuntimeSetProperty(masm); // Check whether the elements is a pixel array. - // eax: value - // ecx: elements array - // ebx: index (as a smi) __ bind(&check_pixel_array); - __ cmp(FieldOperand(ecx, HeapObject::kMapOffset), - Immediate(Factory::pixel_array_map())); - __ j(not_equal, &slow); + // eax: value + // ecx: key + // edx: receiver + // edi: elements array + __ CheckMap(edi, Factory::pixel_array_map(), &slow, true); // Check that the value is a smi. If a conversion is needed call into the // runtime to convert and clamp. __ test(eax, Immediate(kSmiTagMask)); __ j(not_zero, &slow); - __ sar(ebx, kSmiTagSize); // Untag the index. - __ cmp(ebx, FieldOperand(ecx, PixelArray::kLengthOffset)); + __ mov(ebx, ecx); + __ SmiUntag(ebx); + __ cmp(ebx, FieldOperand(edi, PixelArray::kLengthOffset)); __ j(above_equal, &slow); - __ mov(edx, eax); // Save the value. - __ sar(eax, kSmiTagSize); // Untag the value. + __ mov(ecx, eax); // Save the value. Key is not longer needed. + __ SmiUntag(ecx); { // Clamp the value to [0..255]. Label done; - __ test(eax, Immediate(0xFFFFFF00)); + __ test(ecx, Immediate(0xFFFFFF00)); __ j(zero, &done); - __ setcc(negative, eax); // 1 if negative, 0 if positive. - __ dec_b(eax); // 0 if negative, 255 if positive. + __ setcc(negative, ecx); // 1 if negative, 0 if positive. + __ dec_b(ecx); // 0 if negative, 255 if positive. __ bind(&done); } - __ mov(ecx, FieldOperand(ecx, PixelArray::kExternalPointerOffset)); - __ mov_b(Operand(ecx, ebx, times_1, 0), eax); - __ mov(eax, edx); // Return the original value. - __ ret(0); + __ mov(edi, FieldOperand(edi, PixelArray::kExternalPointerOffset)); + __ mov_b(Operand(edi, ebx, times_1, 0), ecx); + __ ret(0); // Return value in eax. // Extra capacity case: Check if there is extra capacity to // perform the store and update the length. Used for adding one // element to the array by writing to array[array.length]. __ bind(&extra); // eax: value - // edx: JSArray - // ecx: FixedArray - // ebx: index (as a smi) - // flags: compare (ebx, edx.length()) + // edx: receiver, a JSArray + // ecx: key, a smi. + // edi: receiver->elements, a FixedArray + // flags: compare (ecx, edx.length()) __ j(not_equal, &slow, not_taken); // do not leave holes in the array - __ sar(ebx, kSmiTagSize); // untag - __ cmp(ebx, FieldOperand(ecx, Array::kLengthOffset)); + __ mov(ebx, ecx); + __ SmiUntag(ebx); // untag + __ cmp(ebx, FieldOperand(edi, Array::kLengthOffset)); __ j(above_equal, &slow, not_taken); - // Restore tag and increment. - __ lea(ebx, Operand(ebx, times_2, 1 << kSmiTagSize)); - __ mov(FieldOperand(edx, JSArray::kLengthOffset), ebx); - __ sub(Operand(ebx), Immediate(1 << kSmiTagSize)); // decrement ebx again + // Add 1 to receiver->length, and go to fast array write. + __ add(FieldOperand(edx, JSArray::kLengthOffset), + Immediate(1 << kSmiTagSize)); __ jmp(&fast); // Array case: Get the length and the elements array from the JS @@ -729,28 +716,26 @@ void KeyedStoreIC::GenerateGeneric(MacroAssembler* masm) { // length is always a smi. __ bind(&array); // eax: value - // edx: JSArray - // ebx: index (as a smi) - __ mov(ecx, FieldOperand(edx, JSObject::kElementsOffset)); - __ cmp(FieldOperand(ecx, HeapObject::kMapOffset), - Immediate(Factory::fixed_array_map())); - __ j(not_equal, &check_pixel_array); + // edx: receiver, a JSArray + // ecx: key, a smi. + __ mov(edi, FieldOperand(edx, JSObject::kElementsOffset)); + __ CheckMap(edi, Factory::fixed_array_map(), &check_pixel_array, true); // Check the key against the length in the array, compute the // address to store into and fall through to fast case. - __ cmp(ebx, FieldOperand(edx, JSArray::kLengthOffset)); + __ cmp(ecx, FieldOperand(edx, JSArray::kLengthOffset)); // Compare smis. __ j(above_equal, &extra, not_taken); // Fast case: Do the store. __ bind(&fast); // eax: value - // ecx: FixedArray - // ebx: index (as a smi) - __ mov(Operand(ecx, ebx, times_2, FixedArray::kHeaderSize - kHeapObjectTag), - eax); + // ecx: key (a smi) + // edx: receiver + // edi: FixedArray receiver->elements + __ mov(FieldOperand(edi, ecx, times_2, FixedArray::kHeaderSize), eax); // Update write barrier for the elements array address. __ mov(edx, Operand(eax)); - __ RecordWrite(ecx, 0, edx, ebx); + __ RecordWrite(edi, 0, edx, ecx); __ ret(0); } @@ -759,92 +744,91 @@ void KeyedStoreIC::GenerateExternalArray(MacroAssembler* masm, ExternalArrayType array_type) { // ----------- S t a t e ------------- // -- eax : value + // -- ecx : key + // -- edx : receiver // -- esp[0] : return address - // -- esp[4] : key - // -- esp[8] : receiver // ----------------------------------- Label slow, check_heap_number; - // Get the receiver from the stack. - __ mov(edx, Operand(esp, 2 * kPointerSize)); // Check that the object isn't a smi. __ test(edx, Immediate(kSmiTagMask)); __ j(zero, &slow); // Get the map from the receiver. - __ mov(ecx, FieldOperand(edx, HeapObject::kMapOffset)); + __ mov(edi, FieldOperand(edx, HeapObject::kMapOffset)); // Check that the receiver does not require access checks. We need // to do this because this generic stub does not perform map checks. - __ movzx_b(ebx, FieldOperand(ecx, Map::kBitFieldOffset)); + __ movzx_b(ebx, FieldOperand(edi, Map::kBitFieldOffset)); __ test(ebx, Immediate(1 << Map::kIsAccessCheckNeeded)); __ j(not_zero, &slow); - // Get the key from the stack. - __ mov(ebx, Operand(esp, 1 * kPointerSize)); // 1 ~ return address // Check that the key is a smi. - __ test(ebx, Immediate(kSmiTagMask)); + __ test(ecx, Immediate(kSmiTagMask)); __ j(not_zero, &slow); // Get the instance type from the map of the receiver. - __ movzx_b(ecx, FieldOperand(ecx, Map::kInstanceTypeOffset)); - // Check that the object is a JS object. - __ cmp(ecx, JS_OBJECT_TYPE); + __ CmpInstanceType(edi, JS_OBJECT_TYPE); __ j(not_equal, &slow); // Check that the elements array is the appropriate type of // ExternalArray. // eax: value - // edx: JSObject - // ebx: index (as a smi) - __ mov(ecx, FieldOperand(edx, JSObject::kElementsOffset)); - Handle<Map> map(Heap::MapForExternalArrayType(array_type)); - __ cmp(FieldOperand(ecx, HeapObject::kMapOffset), - Immediate(map)); - __ j(not_equal, &slow); + // edx: receiver, a JSObject + // ecx: key, a smi + __ mov(edi, FieldOperand(edx, JSObject::kElementsOffset)); + __ CheckMap(edi, Handle<Map>(Heap::MapForExternalArrayType(array_type)), + &slow, true); // Check that the index is in range. - __ sar(ebx, kSmiTagSize); // Untag the index. - __ cmp(ebx, FieldOperand(ecx, ExternalArray::kLengthOffset)); + __ mov(ebx, ecx); + __ SmiUntag(ebx); + __ cmp(ebx, FieldOperand(edi, ExternalArray::kLengthOffset)); // Unsigned comparison catches both negative and too-large values. __ j(above_equal, &slow); // Handle both smis and HeapNumbers in the fast path. Go to the // runtime for all other kinds of values. // eax: value - // ecx: elements array + // edx: receiver + // ecx: key + // edi: elements array // ebx: untagged index __ test(eax, Immediate(kSmiTagMask)); __ j(not_equal, &check_heap_number); // smi case - __ mov(edx, eax); // Save the value. - __ sar(eax, kSmiTagSize); // Untag the value. - __ mov(ecx, FieldOperand(ecx, ExternalArray::kExternalPointerOffset)); + __ mov(ecx, eax); // Preserve the value in eax. Key is no longer needed. + __ SmiUntag(ecx); + __ mov(edi, FieldOperand(edi, ExternalArray::kExternalPointerOffset)); // ecx: base pointer of external storage switch (array_type) { case kExternalByteArray: case kExternalUnsignedByteArray: - __ mov_b(Operand(ecx, ebx, times_1, 0), eax); + __ mov_b(Operand(edi, ebx, times_1, 0), ecx); break; case kExternalShortArray: case kExternalUnsignedShortArray: - __ mov_w(Operand(ecx, ebx, times_2, 0), eax); + __ mov_w(Operand(edi, ebx, times_2, 0), ecx); break; case kExternalIntArray: case kExternalUnsignedIntArray: - __ mov(Operand(ecx, ebx, times_4, 0), eax); + __ mov(Operand(edi, ebx, times_4, 0), ecx); break; case kExternalFloatArray: // Need to perform int-to-float conversion. - __ push(eax); + __ push(ecx); __ fild_s(Operand(esp, 0)); - __ pop(eax); - __ fstp_s(Operand(ecx, ebx, times_4, 0)); + __ pop(ecx); + __ fstp_s(Operand(edi, ebx, times_4, 0)); break; default: UNREACHABLE(); break; } - __ mov(eax, edx); // Return the original value. - __ ret(0); + __ ret(0); // Return the original value. __ bind(&check_heap_number); + // eax: value + // edx: receiver + // ecx: key + // edi: elements array + // ebx: untagged index __ cmp(FieldOperand(eax, HeapObject::kMapOffset), Immediate(Factory::heap_number_map())); __ j(not_equal, &slow); @@ -853,14 +837,12 @@ void KeyedStoreIC::GenerateExternalArray(MacroAssembler* masm, // +/-Infinity into integer arrays basically undefined. For more // reproducible behavior, convert these to zero. __ fld_d(FieldOperand(eax, HeapNumber::kValueOffset)); - __ mov(edx, eax); // Save the value. - __ mov(ecx, FieldOperand(ecx, ExternalArray::kExternalPointerOffset)); + __ mov(edi, FieldOperand(edi, ExternalArray::kExternalPointerOffset)); // ebx: untagged index - // ecx: base pointer of external storage + // edi: base pointer of external storage // top of FPU stack: value if (array_type == kExternalFloatArray) { - __ fstp_s(Operand(ecx, ebx, times_4, 0)); - __ mov(eax, edx); // Return the original value. + __ fstp_s(Operand(edi, ebx, times_4, 0)); __ ret(0); } else { // Need to perform float-to-int conversion. @@ -870,29 +852,27 @@ void KeyedStoreIC::GenerateExternalArray(MacroAssembler* masm, __ j(parity_even, &is_nan); if (array_type != kExternalUnsignedIntArray) { - __ push(eax); // Make room on stack + __ push(ecx); // Make room on stack __ fistp_s(Operand(esp, 0)); - __ pop(eax); + __ pop(ecx); } else { // fistp stores values as signed integers. // To represent the entire range, we need to store as a 64-bit // int and discard the high 32 bits. - __ push(eax); // Make room on stack - __ push(eax); // Make room on stack + __ sub(Operand(esp), Immediate(2 * kPointerSize)); __ fistp_d(Operand(esp, 0)); - __ pop(eax); - __ mov(Operand(esp, 0), eax); - __ pop(eax); + __ pop(ecx); + __ add(Operand(esp), Immediate(kPointerSize)); } - // eax: untagged integer value + // ecx: untagged integer value switch (array_type) { case kExternalByteArray: case kExternalUnsignedByteArray: - __ mov_b(Operand(ecx, ebx, times_1, 0), eax); + __ mov_b(Operand(edi, ebx, times_1, 0), ecx); break; case kExternalShortArray: case kExternalUnsignedShortArray: - __ mov_w(Operand(ecx, ebx, times_2, 0), eax); + __ mov_w(Operand(edi, ebx, times_2, 0), ecx); break; case kExternalIntArray: case kExternalUnsignedIntArray: { @@ -903,21 +883,20 @@ void KeyedStoreIC::GenerateExternalArray(MacroAssembler* masm, // This test would apparently detect both NaN and Infinity, // but we've already checked for NaN using the FPU hardware // above. - __ mov_w(edi, FieldOperand(edx, HeapNumber::kValueOffset + 6)); - __ and_(edi, 0x7FF0); - __ cmp(edi, 0x7FF0); + __ mov_w(edx, FieldOperand(eax, HeapNumber::kValueOffset + 6)); + __ and_(edx, 0x7FF0); + __ cmp(edx, 0x7FF0); __ j(not_equal, ¬_infinity); - __ mov(eax, 0); + __ mov(ecx, 0); __ bind(¬_infinity); - __ mov(Operand(ecx, ebx, times_4, 0), eax); + __ mov(Operand(edi, ebx, times_4, 0), ecx); break; } default: UNREACHABLE(); break; } - __ mov(eax, edx); // Return the original value. - __ ret(0); + __ ret(0); // Return original value. __ bind(&is_nan); __ ffree(); @@ -925,23 +904,22 @@ void KeyedStoreIC::GenerateExternalArray(MacroAssembler* masm, switch (array_type) { case kExternalByteArray: case kExternalUnsignedByteArray: - __ mov_b(Operand(ecx, ebx, times_1, 0), 0); + __ mov_b(Operand(edi, ebx, times_1, 0), 0); break; case kExternalShortArray: case kExternalUnsignedShortArray: - __ mov(eax, 0); - __ mov_w(Operand(ecx, ebx, times_2, 0), eax); + __ xor_(ecx, Operand(ecx)); + __ mov_w(Operand(edi, ebx, times_2, 0), ecx); break; case kExternalIntArray: case kExternalUnsignedIntArray: - __ mov(Operand(ecx, ebx, times_4, 0), Immediate(0)); + __ mov(Operand(edi, ebx, times_4, 0), Immediate(0)); break; default: UNREACHABLE(); break; } - __ mov(eax, edx); // Return the original value. - __ ret(0); + __ ret(0); // Return the original value. } // Slow case: call runtime. @@ -1262,7 +1240,8 @@ void LoadIC::GenerateMiss(MacroAssembler* masm) { __ push(ebx); // return address // Perform tail call to the entry. - __ TailCallRuntime(ExternalReference(IC_Utility(kLoadIC_Miss)), 2, 1); + ExternalReference ref = ExternalReference(IC_Utility(kLoadIC_Miss)); + __ TailCallExternalReference(ref, 2, 1); } @@ -1377,7 +1356,8 @@ void KeyedLoadIC::GenerateMiss(MacroAssembler* masm) { __ push(ebx); // return address // Perform tail call to the entry. - __ TailCallRuntime(ExternalReference(IC_Utility(kKeyedLoadIC_Miss)), 2, 1); + ExternalReference ref = ExternalReference(IC_Utility(kKeyedLoadIC_Miss)); + __ TailCallExternalReference(ref, 2, 1); } @@ -1394,7 +1374,7 @@ void KeyedLoadIC::GenerateRuntimeGetProperty(MacroAssembler* masm) { __ push(ebx); // return address // Perform tail call to the entry. - __ TailCallRuntime(ExternalReference(Runtime::kKeyedGetProperty), 2, 1); + __ TailCallRuntime(Runtime::kKeyedGetProperty, 2, 1); } @@ -1431,7 +1411,8 @@ void StoreIC::GenerateMiss(MacroAssembler* masm) { __ push(ebx); // Perform tail call to the entry. - __ TailCallRuntime(ExternalReference(IC_Utility(kStoreIC_Miss)), 3, 1); + ExternalReference ref = ExternalReference(IC_Utility(kStoreIC_Miss)); + __ TailCallExternalReference(ref, 3, 1); } @@ -1478,7 +1459,8 @@ void StoreIC::GenerateArrayLength(MacroAssembler* masm) { __ push(value); __ push(scratch); // return address - __ TailCallRuntime(ExternalReference(IC_Utility(kStoreIC_ArrayLength)), 2, 1); + ExternalReference ref = ExternalReference(IC_Utility(kStoreIC_ArrayLength)); + __ TailCallExternalReference(ref, 2, 1); __ bind(&miss); @@ -1492,38 +1474,39 @@ Object* KeyedStoreIC_Miss(Arguments args); void KeyedStoreIC::GenerateRuntimeSetProperty(MacroAssembler* masm) { // ----------- S t a t e ------------- // -- eax : value + // -- ecx : key + // -- edx : receiver // -- esp[0] : return address - // -- esp[4] : key - // -- esp[8] : receiver // ----------------------------------- - __ pop(ecx); - __ push(Operand(esp, 1 * kPointerSize)); - __ push(Operand(esp, 1 * kPointerSize)); - __ push(eax); + __ pop(ebx); + __ push(edx); __ push(ecx); + __ push(eax); + __ push(ebx); // Do tail-call to runtime routine. - __ TailCallRuntime(ExternalReference(Runtime::kSetProperty), 3, 1); + __ TailCallRuntime(Runtime::kSetProperty, 3, 1); } void KeyedStoreIC::GenerateMiss(MacroAssembler* masm) { // ----------- S t a t e ------------- // -- eax : value + // -- ecx : key + // -- edx : receiver // -- esp[0] : return address - // -- esp[4] : key - // -- esp[8] : receiver // ----------------------------------- - __ pop(ecx); - __ push(Operand(esp, 1 * kPointerSize)); - __ push(Operand(esp, 1 * kPointerSize)); - __ push(eax); + __ pop(ebx); + __ push(edx); __ push(ecx); + __ push(eax); + __ push(ebx); // Do tail-call to runtime routine. - __ TailCallRuntime(ExternalReference(IC_Utility(kKeyedStoreIC_Miss)), 3, 1); + ExternalReference ref = ExternalReference(IC_Utility(kKeyedStoreIC_Miss)); + __ TailCallExternalReference(ref, 3, 1); } #undef __ |