Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(389)

Unified Diff: src/ia32/ic-ia32.cc

Issue 6529032: Merge 6168:6800 from bleeding_edge to experimental/gc branch. (Closed) Base URL: http://v8.googlecode.com/svn/branches/experimental/gc/
Patch Set: Created 9 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « src/ia32/full-codegen-ia32.cc ('k') | src/ia32/lithium-codegen-ia32.h » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: src/ia32/ic-ia32.cc
===================================================================
--- src/ia32/ic-ia32.cc (revision 6800)
+++ src/ia32/ic-ia32.cc (working copy)
@@ -108,6 +108,9 @@
Register name,
Register r0,
Register r1) {
+ // Assert that name contains a string.
+ if (FLAG_debug_code) __ AbortIfNotString(name);
+
// Compute the capacity mask.
const int kCapacityOffset =
StringDictionary::kHeaderSize +
@@ -388,7 +391,8 @@
}
-void LoadIC::GenerateStringLength(MacroAssembler* masm) {
+void LoadIC::GenerateStringLength(MacroAssembler* masm,
+ bool support_wrappers) {
// ----------- S t a t e -------------
// -- eax : receiver
// -- ecx : name
@@ -396,7 +400,8 @@
// -----------------------------------
Label miss;
- StubCompiler::GenerateLoadStringLength(masm, eax, edx, ebx, &miss);
+ StubCompiler::GenerateLoadStringLength(masm, eax, edx, ebx, &miss,
+ support_wrappers);
__ bind(&miss);
StubCompiler::GenerateLoadMiss(masm, Code::LOAD_IC);
}
@@ -554,19 +559,15 @@
__ ret(0);
__ bind(&check_pixel_array);
- // Check whether the elements is a pixel array.
- // edx: receiver
- // eax: key
- __ mov(ecx, FieldOperand(edx, JSObject::kElementsOffset));
- __ 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);
- __ mov(eax, FieldOperand(ecx, PixelArray::kExternalPointerOffset));
- __ movzx_b(eax, Operand(eax, ebx, times_1, 0));
- __ SmiTag(eax);
- __ ret(0);
+ GenerateFastPixelArrayLoad(masm,
+ edx,
+ eax,
+ ecx,
+ ebx,
+ eax,
+ &check_number_dictionary,
+ NULL,
+ &slow);
__ bind(&check_number_dictionary);
// Check whether the elements is a number dictionary.
@@ -718,160 +719,6 @@
}
-void KeyedLoadIC::GenerateExternalArray(MacroAssembler* masm,
- ExternalArrayType array_type) {
- // ----------- S t a t e -------------
- // -- eax : key
- // -- edx : receiver
- // -- esp[0] : return address
- // -----------------------------------
- Label slow, failed_allocation;
-
- // Check that the object isn't a smi.
- __ test(edx, Immediate(kSmiTagMask));
- __ j(zero, &slow, not_taken);
-
- // Check that the key is a smi.
- __ test(eax, Immediate(kSmiTagMask));
- __ j(not_zero, &slow, not_taken);
-
- // Get the map of the receiver.
- __ mov(ecx, FieldOperand(edx, HeapObject::kMapOffset));
- // Check that the receiver does not require access checks. We need
- // to check this explicitly since this generic stub does not perform
- // map checks.
- __ test_b(FieldOperand(ecx, Map::kBitFieldOffset),
- 1 << Map::kIsAccessCheckNeeded);
- __ j(not_zero, &slow, not_taken);
-
- __ CmpInstanceType(ecx, JS_OBJECT_TYPE);
- __ j(not_equal, &slow, not_taken);
-
- // Check that the elements array is the appropriate type of
- // ExternalArray.
- __ mov(ebx, FieldOperand(edx, JSObject::kElementsOffset));
- Handle<Map> map(Heap::MapForExternalArrayType(array_type));
- __ cmp(FieldOperand(ebx, HeapObject::kMapOffset),
- Immediate(map));
- __ j(not_equal, &slow, not_taken);
-
- // eax: key, known to be a smi.
- // edx: receiver, known to be a JSObject.
- // ebx: elements object, known to be an external array.
- // Check that the index is in range.
- __ mov(ecx, eax);
- __ SmiUntag(ecx); // Untag the index.
- __ cmp(ecx, FieldOperand(ebx, ExternalArray::kLengthOffset));
- // Unsigned comparison catches both negative and too-large values.
- __ j(above_equal, &slow);
-
- __ mov(ebx, FieldOperand(ebx, ExternalArray::kExternalPointerOffset));
- // ebx: base pointer of external storage
- switch (array_type) {
- case kExternalByteArray:
- __ movsx_b(ecx, Operand(ebx, ecx, times_1, 0));
- break;
- case kExternalUnsignedByteArray:
- __ movzx_b(ecx, Operand(ebx, ecx, times_1, 0));
- break;
- case kExternalShortArray:
- __ movsx_w(ecx, Operand(ebx, ecx, times_2, 0));
- break;
- case kExternalUnsignedShortArray:
- __ movzx_w(ecx, Operand(ebx, ecx, times_2, 0));
- break;
- case kExternalIntArray:
- case kExternalUnsignedIntArray:
- __ mov(ecx, Operand(ebx, ecx, times_4, 0));
- break;
- case kExternalFloatArray:
- __ fld_s(Operand(ebx, ecx, times_4, 0));
- break;
- default:
- UNREACHABLE();
- break;
- }
-
- // For integer array types:
- // ecx: value
- // For floating-point array type:
- // FP(0): value
-
- if (array_type == kExternalIntArray ||
- array_type == kExternalUnsignedIntArray) {
- // For the Int and UnsignedInt array types, we need to see whether
- // the value can be represented in a Smi. If not, we need to convert
- // it to a HeapNumber.
- Label box_int;
- if (array_type == kExternalIntArray) {
- __ cmp(ecx, 0xC0000000);
- __ j(sign, &box_int);
- } else {
- ASSERT_EQ(array_type, kExternalUnsignedIntArray);
- // The test is different for unsigned int values. Since we need
- // the value to be in the range of a positive smi, we can't
- // handle either of the top two bits being set in the value.
- __ test(ecx, Immediate(0xC0000000));
- __ j(not_zero, &box_int);
- }
-
- __ mov(eax, ecx);
- __ SmiTag(eax);
- __ ret(0);
-
- __ bind(&box_int);
-
- // Allocate a HeapNumber for the int and perform int-to-double
- // conversion.
- if (array_type == kExternalIntArray) {
- __ push(ecx);
- __ fild_s(Operand(esp, 0));
- __ pop(ecx);
- } else {
- ASSERT(array_type == kExternalUnsignedIntArray);
- // Need to zero-extend the value.
- // There's no fild variant for unsigned values, so zero-extend
- // to a 64-bit int manually.
- __ push(Immediate(0));
- __ push(ecx);
- __ fild_d(Operand(esp, 0));
- __ pop(ecx);
- __ pop(ecx);
- }
- // FP(0): value
- __ AllocateHeapNumber(ecx, ebx, edi, &failed_allocation);
- // Set the value.
- __ mov(eax, ecx);
- __ fstp_d(FieldOperand(eax, HeapNumber::kValueOffset));
- __ ret(0);
- } else if (array_type == kExternalFloatArray) {
- // For the floating-point array type, we need to always allocate a
- // HeapNumber.
- __ AllocateHeapNumber(ecx, ebx, edi, &failed_allocation);
- // Set the value.
- __ mov(eax, ecx);
- __ fstp_d(FieldOperand(eax, HeapNumber::kValueOffset));
- __ ret(0);
- } else {
- __ mov(eax, ecx);
- __ SmiTag(eax);
- __ ret(0);
- }
-
- // If we fail allocation of the HeapNumber, we still have a value on
- // top of the FPU stack. Remove it.
- __ bind(&failed_allocation);
- __ ffree();
- __ fincstp();
- // Fall through to slow case.
-
- // Slow case: Jump to runtime.
- __ bind(&slow);
- __ IncrementCounter(&Counters::keyed_load_external_array_slow, 1);
- GenerateRuntimeGetProperty(masm);
-}
-
-
void KeyedLoadIC::GenerateIndexedInterceptor(MacroAssembler* masm) {
// ----------- S t a t e -------------
// -- eax : key
@@ -962,28 +809,17 @@
// ecx: key (a smi)
// 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);
- __ mov(ebx, ecx);
- __ SmiUntag(ebx);
- __ cmp(ebx, FieldOperand(edi, PixelArray::kLengthOffset));
- __ j(above_equal, &slow);
- __ mov(ecx, eax); // Save the value. Key is not longer needed.
- __ SmiUntag(ecx);
- { // Clamp the value to [0..255].
- Label done;
- __ test(ecx, Immediate(0xFFFFFF00));
- __ j(zero, &done);
- __ setcc(negative, ecx); // 1 if negative, 0 if positive.
- __ dec_b(ecx); // 0 if negative, 255 if positive.
- __ bind(&done);
- }
- __ mov(edi, FieldOperand(edi, PixelArray::kExternalPointerOffset));
- __ mov_b(Operand(edi, ebx, times_1, 0), ecx);
- __ ret(0); // Return value in eax.
+ GenerateFastPixelArrayStore(masm,
+ edx,
+ ecx,
+ eax,
+ edi,
+ ebx,
+ false,
+ NULL,
+ &slow,
+ &slow,
+ &slow);
// Extra capacity case: Check if there is extra capacity to
// perform the store and update the length. Used for adding one
@@ -1032,194 +868,6 @@
}
-void KeyedStoreIC::GenerateExternalArray(MacroAssembler* masm,
- ExternalArrayType array_type) {
- // ----------- S t a t e -------------
- // -- eax : value
- // -- ecx : key
- // -- edx : receiver
- // -- esp[0] : return address
- // -----------------------------------
- Label slow, check_heap_number;
-
- // Check that the object isn't a smi.
- __ test(edx, Immediate(kSmiTagMask));
- __ j(zero, &slow);
- // Get the map from the receiver.
- __ 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.
- __ test_b(FieldOperand(edi, Map::kBitFieldOffset),
- 1 << Map::kIsAccessCheckNeeded);
- __ j(not_zero, &slow);
- // Check that the key is a smi.
- __ test(ecx, Immediate(kSmiTagMask));
- __ j(not_zero, &slow);
- // Get the instance type from the map of the receiver.
- __ CmpInstanceType(edi, JS_OBJECT_TYPE);
- __ j(not_equal, &slow);
-
- // Check that the elements array is the appropriate type of
- // ExternalArray.
- // eax: value
- // 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.
- __ 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
- // edx: receiver
- // ecx: key
- // edi: elements array
- // ebx: untagged index
- __ test(eax, Immediate(kSmiTagMask));
- __ j(not_equal, &check_heap_number);
- // smi case
- __ 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(edi, ebx, times_1, 0), ecx);
- break;
- case kExternalShortArray:
- case kExternalUnsignedShortArray:
- __ mov_w(Operand(edi, ebx, times_2, 0), ecx);
- break;
- case kExternalIntArray:
- case kExternalUnsignedIntArray:
- __ mov(Operand(edi, ebx, times_4, 0), ecx);
- break;
- case kExternalFloatArray:
- // Need to perform int-to-float conversion.
- __ push(ecx);
- __ fild_s(Operand(esp, 0));
- __ pop(ecx);
- __ fstp_s(Operand(edi, ebx, times_4, 0));
- break;
- default:
- UNREACHABLE();
- break;
- }
- __ 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);
-
- // The WebGL specification leaves the behavior of storing NaN and
- // +/-Infinity into integer arrays basically undefined. For more
- // reproducible behavior, convert these to zero.
- __ fld_d(FieldOperand(eax, HeapNumber::kValueOffset));
- __ mov(edi, FieldOperand(edi, ExternalArray::kExternalPointerOffset));
- // ebx: untagged index
- // edi: base pointer of external storage
- // top of FPU stack: value
- if (array_type == kExternalFloatArray) {
- __ fstp_s(Operand(edi, ebx, times_4, 0));
- __ ret(0);
- } else {
- // Need to perform float-to-int conversion.
- // Test the top of the FP stack for NaN.
- Label is_nan;
- __ fucomi(0);
- __ j(parity_even, &is_nan);
-
- if (array_type != kExternalUnsignedIntArray) {
- __ push(ecx); // Make room on stack
- __ fistp_s(Operand(esp, 0));
- __ 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.
- __ sub(Operand(esp), Immediate(2 * kPointerSize));
- __ fistp_d(Operand(esp, 0));
- __ pop(ecx);
- __ add(Operand(esp), Immediate(kPointerSize));
- }
- // ecx: untagged integer value
- switch (array_type) {
- case kExternalByteArray:
- case kExternalUnsignedByteArray:
- __ mov_b(Operand(edi, ebx, times_1, 0), ecx);
- break;
- case kExternalShortArray:
- case kExternalUnsignedShortArray:
- __ mov_w(Operand(edi, ebx, times_2, 0), ecx);
- break;
- case kExternalIntArray:
- case kExternalUnsignedIntArray: {
- // We also need to explicitly check for +/-Infinity. These are
- // converted to MIN_INT, but we need to be careful not to
- // confuse with legal uses of MIN_INT.
- Label not_infinity;
- // This test would apparently detect both NaN and Infinity,
- // but we've already checked for NaN using the FPU hardware
- // above.
- __ mov_w(edx, FieldOperand(eax, HeapNumber::kValueOffset + 6));
- __ and_(edx, 0x7FF0);
- __ cmp(edx, 0x7FF0);
- __ j(not_equal, &not_infinity);
- __ mov(ecx, 0);
- __ bind(&not_infinity);
- __ mov(Operand(edi, ebx, times_4, 0), ecx);
- break;
- }
- default:
- UNREACHABLE();
- break;
- }
- __ ret(0); // Return original value.
-
- __ bind(&is_nan);
- __ ffree();
- __ fincstp();
- switch (array_type) {
- case kExternalByteArray:
- case kExternalUnsignedByteArray:
- __ mov_b(Operand(edi, ebx, times_1, 0), 0);
- break;
- case kExternalShortArray:
- case kExternalUnsignedShortArray:
- __ Set(ecx, Immediate(0));
- __ mov_w(Operand(edi, ebx, times_2, 0), ecx);
- break;
- case kExternalIntArray:
- case kExternalUnsignedIntArray:
- __ mov(Operand(edi, ebx, times_4, 0), Immediate(0));
- break;
- default:
- UNREACHABLE();
- break;
- }
- __ ret(0); // Return the original value.
- }
-
- // Slow case: call runtime.
- __ bind(&slow);
- GenerateRuntimeSetProperty(masm);
-}
-
-
// The generated code does not accept smi keys.
// The generated code falls through if both probes miss.
static void GenerateMonomorphicCacheProbe(MacroAssembler* masm,
@@ -1232,8 +880,12 @@
Label number, non_number, non_string, boolean, probe, miss;
// Probe the stub cache.
- Code::Flags flags =
- Code::ComputeFlags(kind, NOT_IN_LOOP, MONOMORPHIC, NORMAL, argc);
+ Code::Flags flags = Code::ComputeFlags(kind,
+ NOT_IN_LOOP,
+ MONOMORPHIC,
+ Code::kNoExtraICState,
+ NORMAL,
+ argc);
StubCache::GenerateProbe(masm, flags, edx, ecx, ebx, eax);
// If the stub cache probing failed, the receiver might be a value.
@@ -1326,7 +978,9 @@
}
-static void GenerateCallMiss(MacroAssembler* masm, int argc, IC::UtilityId id) {
+static void GenerateCallMiss(MacroAssembler* masm,
+ int argc,
+ IC::UtilityId id) {
// ----------- S t a t e -------------
// -- ecx : name
// -- esp[0] : return address
@@ -1547,7 +1201,14 @@
// -- esp[(argc + 1) * 4] : receiver
// -----------------------------------
+ // Check if the name is a string.
+ Label miss;
+ __ test(ecx, Immediate(kSmiTagMask));
+ __ j(zero, &miss);
+ Condition cond = masm->IsObjectStringType(ecx, eax, eax);
+ __ j(NegateCondition(cond), &miss);
GenerateCallNormal(masm, argc);
+ __ bind(&miss);
GenerateMiss(masm, argc);
}
@@ -1827,7 +1488,8 @@
}
-void StoreIC::GenerateMegamorphic(MacroAssembler* masm) {
+void StoreIC::GenerateMegamorphic(MacroAssembler* masm,
+ Code::ExtraICState extra_ic_state) {
// ----------- S t a t e -------------
// -- eax : value
// -- ecx : name
@@ -1837,7 +1499,8 @@
Code::Flags flags = Code::ComputeFlags(Code::STORE_IC,
NOT_IN_LOOP,
- MONOMORPHIC);
+ MONOMORPHIC,
+ extra_ic_state);
StubCache::GenerateProbe(masm, flags, edx, ecx, ebx, no_reg);
// Cache miss: Jump to runtime.
« no previous file with comments | « src/ia32/full-codegen-ia32.cc ('k') | src/ia32/lithium-codegen-ia32.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698