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

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

Issue 8139027: Version 3.6.5 (Closed) Base URL: http://v8.googlecode.com/svn/trunk/
Patch Set: '' Created 9 years, 2 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 9531)
+++ src/ia32/ic-ia32.cc (working copy)
@@ -212,7 +212,7 @@
// Update write barrier. Make sure not to clobber the value.
__ mov(r1, value);
- __ RecordWrite(elements, r0, r1);
+ __ RecordWrite(elements, r0, r1, kDontSaveFPRegs);
}
@@ -326,7 +326,7 @@
// Fast case: Do the load.
STATIC_ASSERT((kPointerSize == 4) && (kSmiTagSize == 1) && (kSmiTag == 0));
__ mov(scratch, FieldOperand(scratch, key, times_2, FixedArray::kHeaderSize));
- __ cmp(Operand(scratch), Immediate(FACTORY->the_hole_value()));
+ __ cmp(scratch, 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.
__ j(equal, out_of_range);
@@ -394,8 +394,8 @@
// Check if element is in the range of mapped arguments. If not, jump
// to the unmapped lookup with the parameter map in scratch1.
__ mov(scratch2, FieldOperand(scratch1, FixedArray::kLengthOffset));
- __ sub(Operand(scratch2), Immediate(Smi::FromInt(2)));
- __ cmp(key, Operand(scratch2));
+ __ sub(scratch2, Immediate(Smi::FromInt(2)));
+ __ cmp(key, scratch2);
__ j(greater_equal, unmapped_case);
// Load element index and check whether it is the hole.
@@ -432,7 +432,7 @@
Handle<Map> fixed_array_map(masm->isolate()->heap()->fixed_array_map());
__ CheckMap(backing_store, fixed_array_map, slow_case, DONT_DO_SMI_CHECK);
__ mov(scratch, FieldOperand(backing_store, FixedArray::kLengthOffset));
- __ cmp(key, Operand(scratch));
+ __ cmp(key, scratch);
__ j(greater_equal, slow_case);
return FieldOperand(backing_store,
key,
@@ -534,7 +534,7 @@
__ shr(ecx, KeyedLookupCache::kMapHashShift);
__ mov(edi, FieldOperand(eax, String::kHashFieldOffset));
__ shr(edi, String::kHashShift);
- __ xor_(ecx, Operand(edi));
+ __ xor_(ecx, edi);
__ and_(ecx, KeyedLookupCache::kCapacityMask);
// Load the key (consisting of map and symbol) from the cache and
@@ -545,7 +545,7 @@
__ shl(edi, kPointerSizeLog2 + 1);
__ cmp(ebx, Operand::StaticArray(edi, times_1, cache_keys));
__ j(not_equal, &slow);
- __ add(Operand(edi), Immediate(kPointerSize));
+ __ add(edi, Immediate(kPointerSize));
__ cmp(eax, Operand::StaticArray(edi, times_1, cache_keys));
__ j(not_equal, &slow);
@@ -559,12 +559,12 @@
__ mov(edi,
Operand::StaticArray(ecx, times_pointer_size, cache_field_offsets));
__ movzx_b(ecx, FieldOperand(ebx, Map::kInObjectPropertiesOffset));
- __ sub(edi, Operand(ecx));
+ __ sub(edi, ecx);
__ j(above_equal, &property_array_property);
// Load in-object property.
__ movzx_b(ecx, FieldOperand(ebx, Map::kInstanceSizeOffset));
- __ add(ecx, Operand(edi));
+ __ add(ecx, edi);
__ mov(eax, FieldOperand(edx, ecx, times_pointer_size, 0));
__ IncrementCounter(counters->keyed_load_generic_lookup_cache(), 1);
__ ret(0);
@@ -651,8 +651,8 @@
// Check that it has indexed interceptor and access checks
// are not enabled for this object.
__ movzx_b(ecx, FieldOperand(ecx, Map::kBitFieldOffset));
- __ and_(Operand(ecx), Immediate(kSlowCaseBitFieldMask));
- __ cmp(Operand(ecx), Immediate(1 << Map::kHasIndexedInterceptor));
+ __ and_(ecx, Immediate(kSlowCaseBitFieldMask));
+ __ cmp(ecx, Immediate(1 << Map::kHasIndexedInterceptor));
__ j(not_zero, &slow);
// Everything is fine, call runtime.
@@ -710,7 +710,7 @@
__ mov(mapped_location, eax);
__ lea(ecx, mapped_location);
__ mov(edx, eax);
- __ RecordWrite(ebx, ecx, edx);
+ __ RecordWrite(ebx, ecx, edx, kDontSaveFPRegs);
__ Ret();
__ bind(&notin);
// The unmapped lookup expects that the parameter map is in ebx.
@@ -719,7 +719,7 @@
__ mov(unmapped_location, eax);
__ lea(edi, unmapped_location);
__ mov(edx, eax);
- __ RecordWrite(ebx, edi, edx);
+ __ RecordWrite(ebx, edi, edx, kDontSaveFPRegs);
__ Ret();
__ bind(&slow);
GenerateMiss(masm, false);
@@ -734,7 +734,9 @@
// -- edx : receiver
// -- esp[0] : return address
// -----------------------------------
- Label slow, fast, array, extra;
+ Label slow, fast_object_with_map_check, fast_object_without_map_check;
+ Label fast_double_with_map_check, fast_double_without_map_check;
+ Label check_if_double_array, array, extra;
// Check that the object isn't a smi.
__ JumpIfSmi(edx, &slow);
@@ -750,22 +752,18 @@
__ CmpInstanceType(edi, JS_ARRAY_TYPE);
__ j(equal, &array);
// Check that the object is some kind of JSObject.
- __ CmpInstanceType(edi, FIRST_JS_RECEIVER_TYPE);
+ __ CmpInstanceType(edi, FIRST_JS_OBJECT_TYPE);
__ j(below, &slow);
- __ CmpInstanceType(edi, JS_PROXY_TYPE);
- __ j(equal, &slow);
- __ CmpInstanceType(edi, JS_FUNCTION_PROXY_TYPE);
- __ j(equal, &slow);
// Object case: Check key against length in the elements array.
// eax: value
// edx: JSObject
// ecx: key (a smi)
- __ mov(edi, FieldOperand(edx, JSObject::kElementsOffset));
- // Check that the object is in fast mode and writable.
- __ CheckMap(edi, FACTORY->fixed_array_map(), &slow, DONT_DO_SMI_CHECK);
- __ cmp(ecx, FieldOperand(edi, FixedArray::kLengthOffset));
- __ j(below, &fast);
+ // edi: receiver map
+ __ mov(ebx, FieldOperand(edx, JSObject::kElementsOffset));
+ // Check array bounds. Both the key and the length of FixedArray are smis.
+ __ cmp(ecx, FieldOperand(ebx, FixedArray::kLengthOffset));
+ __ j(below, &fast_object_with_map_check);
// Slow case: call runtime.
__ bind(&slow);
@@ -778,17 +776,29 @@
// eax: value
// edx: receiver, a JSArray
// ecx: key, a smi.
- // edi: receiver->elements, a FixedArray
+ // ebx: receiver->elements, a FixedArray
+ // edi: receiver map
// flags: compare (ecx, edx.length())
// do not leave holes in the array:
__ j(not_equal, &slow);
- __ cmp(ecx, FieldOperand(edi, FixedArray::kLengthOffset));
+ __ cmp(ecx, FieldOperand(ebx, FixedArray::kLengthOffset));
__ j(above_equal, &slow);
- // Add 1 to receiver->length, and go to fast array write.
+ __ mov(edi, FieldOperand(ebx, HeapObject::kMapOffset));
+ __ cmp(edi, masm->isolate()->factory()->fixed_array_map());
+ __ j(not_equal, &check_if_double_array);
+ // Add 1 to receiver->length, and go to common element store code for Objects.
__ add(FieldOperand(edx, JSArray::kLengthOffset),
Immediate(Smi::FromInt(1)));
- __ jmp(&fast);
+ __ jmp(&fast_object_without_map_check);
+ __ bind(&check_if_double_array);
+ __ cmp(edi, masm->isolate()->factory()->fixed_double_array_map());
+ __ j(not_equal, &slow);
+ // Add 1 to receiver->length, and go to common element store code for doubles.
+ __ add(FieldOperand(edx, JSArray::kLengthOffset),
+ Immediate(Smi::FromInt(1)));
+ __ jmp(&fast_double_without_map_check);
+
// Array case: Get the length and the elements array from the JS
// array. Check that the array is in fast mode (and writable); if it
// is the length is always a smi.
@@ -796,25 +806,57 @@
// eax: value
// edx: receiver, a JSArray
// ecx: key, a smi.
- __ mov(edi, FieldOperand(edx, JSObject::kElementsOffset));
- __ CheckMap(edi, FACTORY->fixed_array_map(), &slow, DONT_DO_SMI_CHECK);
+ // edi: receiver map
+ __ mov(ebx, FieldOperand(edx, JSObject::kElementsOffset));
- // Check the key against the length in the array, compute the
- // address to store into and fall through to fast case.
+ // Check the key against the length in the array and fall through to the
+ // common store code.
__ cmp(ecx, FieldOperand(edx, JSArray::kLengthOffset)); // Compare smis.
__ j(above_equal, &extra);
- // Fast case: Do the store.
- __ bind(&fast);
+ // Fast case: Do the store, could either Object or double.
+ __ bind(&fast_object_with_map_check);
// eax: value
// ecx: key (a smi)
// edx: receiver
- // edi: FixedArray receiver->elements
- __ mov(CodeGenerator::FixedArrayElementOperand(edi, ecx), eax);
+ // ebx: FixedArray receiver->elements
+ // edi: receiver map
+ __ mov(edi, FieldOperand(ebx, HeapObject::kMapOffset));
+ __ cmp(edi, masm->isolate()->factory()->fixed_array_map());
+ __ j(not_equal, &fast_double_with_map_check);
+ __ bind(&fast_object_without_map_check);
+ // Smi stores don't require further checks.
+ Label non_smi_value;
+ __ JumpIfNotSmi(eax, &non_smi_value);
+ // It's irrelevant whether array is smi-only or not when writing a smi.
+ __ mov(CodeGenerator::FixedArrayElementOperand(ebx, ecx), eax);
+ __ ret(0);
+
+ __ bind(&non_smi_value);
+ if (FLAG_smi_only_arrays) {
+ // Escape to slow case when writing non-smi into smi-only array.
+ __ mov(edi, FieldOperand(edx, HeapObject::kMapOffset));
+ __ CheckFastObjectElements(edi, &slow, Label::kNear);
+ }
+
+ // Fast elements array, store the value to the elements backing store.
+ __ mov(CodeGenerator::FixedArrayElementOperand(ebx, ecx), eax);
// Update write barrier for the elements array address.
- __ mov(edx, Operand(eax));
- __ RecordWrite(edi, 0, edx, ecx);
+ __ mov(edx, eax); // Preserve the value which is returned.
+ __ RecordWriteArray(
+ ebx, edx, ecx, kDontSaveFPRegs, EMIT_REMEMBERED_SET, OMIT_SMI_CHECK);
__ ret(0);
+
+ __ bind(&fast_double_with_map_check);
+ // Check for fast double array case. If this fails, call through to the
+ // runtime.
+ __ cmp(edi, masm->isolate()->factory()->fixed_double_array_map());
+ __ j(not_equal, &slow);
+ __ bind(&fast_double_without_map_check);
+ // If the value is a number, store it as a double in the FastDoubleElements
+ // array.
+ __ StoreNumberToDoubleElements(eax, ebx, ecx, edx, xmm0, &slow, false);
+ __ ret(0);
}
@@ -951,22 +993,22 @@
// Get the receiver of the function from the stack; 1 ~ return address.
__ mov(edx, Operand(esp, (argc + 1) * kPointerSize));
- // Enter an internal frame.
- __ EnterInternalFrame();
+ {
+ FrameScope scope(masm, StackFrame::INTERNAL);
- // Push the receiver and the name of the function.
- __ push(edx);
- __ push(ecx);
+ // Push the receiver and the name of the function.
+ __ push(edx);
+ __ push(ecx);
- // Call the entry.
- CEntryStub stub(1);
- __ mov(eax, Immediate(2));
- __ mov(ebx, Immediate(ExternalReference(IC_Utility(id), masm->isolate())));
- __ CallStub(&stub);
+ // Call the entry.
+ CEntryStub stub(1);
+ __ mov(eax, Immediate(2));
+ __ mov(ebx, Immediate(ExternalReference(IC_Utility(id), masm->isolate())));
+ __ CallStub(&stub);
- // Move result to edi and exit the internal frame.
- __ mov(edi, eax);
- __ LeaveInternalFrame();
+ // Move result to edi and exit the internal frame.
+ __ mov(edi, eax);
+ }
// Check if the receiver is a global object of some sort.
// This can happen only for regular CallIC but not KeyedCallIC.
@@ -1111,13 +1153,17 @@
// This branch is taken when calling KeyedCallIC_Miss is neither required
// nor beneficial.
__ IncrementCounter(counters->keyed_call_generic_slow_load(), 1);
- __ EnterInternalFrame();
- __ push(ecx); // save the key
- __ push(edx); // pass the receiver
- __ push(ecx); // pass the key
- __ CallRuntime(Runtime::kKeyedGetProperty, 2);
- __ pop(ecx); // restore the key
- __ LeaveInternalFrame();
+
+ {
+ FrameScope scope(masm, StackFrame::INTERNAL);
+ __ push(ecx); // save the key
+ __ push(edx); // pass the receiver
+ __ push(ecx); // pass the key
+ __ CallRuntime(Runtime::kKeyedGetProperty, 2);
+ __ pop(ecx); // restore the key
+ // Leave the internal frame.
+ }
+
__ mov(edi, eax);
__ jmp(&do_call);
« 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