Index: src/ia32/ic-ia32.cc |
=================================================================== |
--- src/ia32/ic-ia32.cc (revision 4872) |
+++ src/ia32/ic-ia32.cc (working copy) |
@@ -306,22 +306,22 @@ |
// Falls through for regular JS object. |
static void GenerateKeyedLoadReceiverCheck(MacroAssembler* masm, |
Register receiver, |
- Register r0, |
+ Register map, |
Label* slow) { |
// Register use: |
// receiver - holds the receiver and is unchanged. |
// Scratch registers: |
- // r0 - used to hold the map of the receiver. |
+ // map - used to hold the map of the receiver. |
// Check that the object isn't a smi. |
__ test(receiver, Immediate(kSmiTagMask)); |
__ j(zero, slow, not_taken); |
// Get the map of the receiver. |
- __ mov(r0, FieldOperand(receiver, HeapObject::kMapOffset)); |
+ __ mov(map, FieldOperand(receiver, HeapObject::kMapOffset)); |
// Check bit field. |
- __ test_b(FieldOperand(r0, Map::kBitFieldOffset), |
+ __ test_b(FieldOperand(map, Map::kBitFieldOffset), |
KeyedLoadIC::kSlowCaseBitFieldMask); |
__ j(not_zero, slow, not_taken); |
// Check that the object is some kind of JS object EXCEPT JS Value type. |
@@ -330,7 +330,7 @@ |
// into string objects works as intended. |
ASSERT(JS_OBJECT_TYPE > JS_VALUE_TYPE); |
- __ CmpInstanceType(r0, JS_OBJECT_TYPE); |
+ __ CmpInstanceType(map, JS_OBJECT_TYPE); |
__ j(below, slow, not_taken); |
} |
@@ -371,7 +371,7 @@ |
// Checks whether a key is an array index string or a symbol string. |
-// Falls through if a key is a symbol. |
+// Falls through if the key is a symbol. |
static void GenerateKeyStringCheck(MacroAssembler* masm, |
Register key, |
Register map, |
@@ -399,11 +399,9 @@ |
// Picks out an array index from the hash field. |
-// The generated code never falls through. |
static void GenerateIndexFromHash(MacroAssembler* masm, |
Register key, |
- Register hash, |
- Label* index_smi) { |
+ Register hash) { |
// Register use: |
// key - holds the overwritten key on exit. |
// hash - holds the key's hash. Clobbered. |
@@ -415,8 +413,6 @@ |
(1 << String::kArrayIndexValueBits)); |
// We want the smi-tagged index in key. kArrayIndexValueMask has zeros in |
// the low kHashShift bits. |
- // key: string key |
- // ebx: hash field. |
ASSERT(String::kHashShift >= kSmiTagSize); |
__ and_(hash, String::kArrayIndexValueMask); |
__ shr(hash, String::kHashShift - kSmiTagSize); |
@@ -424,8 +420,6 @@ |
// runtime later. However as the new key is the numeric value of a string key |
// there is no difference in using either key. |
__ mov(key, hash); |
- // Now jump to the place where smi keys are handled. |
- __ jmp(index_smi); |
} |
@@ -574,7 +568,9 @@ |
__ ret(0); |
__ bind(&index_string); |
- GenerateIndexFromHash(masm, eax, ebx, &index_smi); |
+ GenerateIndexFromHash(masm, eax, ebx); |
+ // Now jump to the place where smi keys are handled. |
+ __ jmp(&index_smi); |
} |
@@ -1125,13 +1121,12 @@ |
// The generated code falls through if both probes miss. |
static void GenerateMonomorphicCacheProbe(MacroAssembler* masm, |
int argc, |
- Code::Kind kind, |
- Label* miss) { |
+ Code::Kind kind) { |
// ----------- S t a t e ------------- |
// -- ecx : name |
// -- edx : receiver |
// ----------------------------------- |
- Label number, non_number, non_string, boolean, probe; |
+ Label number, non_number, non_string, boolean, probe, miss; |
// Probe the stub cache. |
Code::Flags flags = |
@@ -1166,7 +1161,7 @@ |
__ cmp(edx, Factory::true_value()); |
__ j(equal, &boolean, not_taken); |
__ cmp(edx, Factory::false_value()); |
- __ j(not_equal, miss, taken); |
+ __ j(not_equal, &miss, taken); |
__ bind(&boolean); |
StubCompiler::GenerateLoadGlobalFunctionPrototype( |
masm, Context::BOOLEAN_FUNCTION_INDEX, edx); |
@@ -1174,6 +1169,7 @@ |
// Probe the stub cache for the value object. |
__ bind(&probe); |
StubCache::GenerateProbe(masm, flags, edx, ecx, ebx, no_reg); |
+ __ bind(&miss); |
} |
@@ -1214,8 +1210,8 @@ |
__ InvokeFunction(edi, actual, JUMP_FUNCTION); |
} |
-// The generated code never falls through. |
-static void GenerateCallNormal(MacroAssembler* masm, int argc, Label* miss) { |
+// The generated code falls through if the call should be handled by runtime. |
+static void GenerateCallNormal(MacroAssembler* masm, int argc) { |
// ----------- S t a t e ------------- |
// -- ecx : name |
// -- esp[0] : return address |
@@ -1223,20 +1219,20 @@ |
// -- ... |
// -- esp[(argc + 1) * 4] : receiver |
// ----------------------------------- |
- Label global_object, non_global_object; |
+ Label miss, global_object, non_global_object; |
// Get the receiver of the function from the stack; 1 ~ return address. |
__ mov(edx, Operand(esp, (argc + 1) * kPointerSize)); |
// Check that the receiver isn't a smi. |
__ test(edx, Immediate(kSmiTagMask)); |
- __ j(zero, miss, not_taken); |
+ __ j(zero, &miss, not_taken); |
// Check that the receiver is a valid JS object. |
__ mov(ebx, FieldOperand(edx, HeapObject::kMapOffset)); |
__ movzx_b(eax, FieldOperand(ebx, Map::kInstanceTypeOffset)); |
__ cmp(eax, FIRST_JS_OBJECT_TYPE); |
- __ j(below, miss, not_taken); |
+ __ j(below, &miss, not_taken); |
// If this assert fails, we have to check upper bound too. |
ASSERT(LAST_TYPE == JS_FUNCTION_TYPE); |
@@ -1252,8 +1248,8 @@ |
// Check that the global object does not require access checks. |
__ test_b(FieldOperand(ebx, Map::kBitFieldOffset), |
1 << Map::kIsAccessCheckNeeded); |
- __ j(not_equal, miss, not_taken); |
- GenerateNormalHelper(masm, argc, true, miss); |
+ __ j(not_equal, &miss, not_taken); |
+ GenerateNormalHelper(masm, argc, true, &miss); |
// Accessing non-global object: Check for access to global proxy. |
Label global_proxy, invoke; |
@@ -1264,14 +1260,16 @@ |
// require access checks. |
__ test_b(FieldOperand(ebx, Map::kBitFieldOffset), |
1 << Map::kIsAccessCheckNeeded); |
- __ j(not_equal, miss, not_taken); |
+ __ j(not_equal, &miss, not_taken); |
__ bind(&invoke); |
- GenerateNormalHelper(masm, argc, false, miss); |
+ GenerateNormalHelper(masm, argc, false, &miss); |
// Global object proxy access: Check access rights. |
__ bind(&global_proxy); |
- __ CheckAccessGlobalProxy(edx, eax, miss); |
+ __ CheckAccessGlobalProxy(edx, eax, &miss); |
__ jmp(&invoke); |
+ |
+ __ bind(&miss); |
} |
@@ -1337,24 +1335,36 @@ |
// -- esp[(argc + 1) * 4] : receiver |
// ----------------------------------- |
- Label miss; |
// Get the receiver of the function from the stack; 1 ~ return address. |
__ mov(edx, Operand(esp, (argc + 1) * kPointerSize)); |
- GenerateMonomorphicCacheProbe(masm, argc, Code::CALL_IC, &miss); |
- __ bind(&miss); |
+ GenerateMonomorphicCacheProbe(masm, argc, Code::CALL_IC); |
GenerateMiss(masm, argc); |
} |
void CallIC::GenerateNormal(MacroAssembler* masm, int argc) { |
- Label miss; |
- GenerateCallNormal(masm, argc, &miss); |
- __ bind(&miss); |
+ // ----------- S t a t e ------------- |
+ // -- ecx : name |
+ // -- esp[0] : return address |
+ // -- esp[(argc - n) * 4] : arg[n] (zero-based) |
+ // -- ... |
+ // -- esp[(argc + 1) * 4] : receiver |
+ // ----------------------------------- |
+ |
+ GenerateCallNormal(masm, argc); |
GenerateMiss(masm, argc); |
} |
void CallIC::GenerateMiss(MacroAssembler* masm, int argc) { |
+ // ----------- S t a t e ------------- |
+ // -- ecx : name |
+ // -- esp[0] : return address |
+ // -- esp[(argc - n) * 4] : arg[n] (zero-based) |
+ // -- ... |
+ // -- esp[(argc + 1) * 4] : receiver |
+ // ----------------------------------- |
+ |
GenerateCallMiss(masm, argc, IC::kCallIC_Miss); |
} |
@@ -1385,13 +1395,8 @@ |
GenerateKeyedLoadReceiverCheck(masm, edx, eax, &slow_call); |
- GenerateFastArrayLoad(masm, |
- edx, |
- ecx, |
- eax, |
- edi, |
- &check_number_dictionary, |
- &slow_load); |
+ GenerateFastArrayLoad( |
+ masm, edx, ecx, eax, edi, &check_number_dictionary, &slow_load); |
__ IncrementCounter(&Counters::keyed_call_generic_smi_fast, 1); |
__ bind(&do_call); |
@@ -1417,14 +1422,8 @@ |
__ SmiUntag(ebx); |
// ebx: untagged index |
// Receiver in edx will be clobbered, need to reload it on miss. |
- GenerateNumberDictionaryLoad(masm, |
- &slow_reload_receiver, |
- eax, |
- ecx, |
- ebx, |
- edx, |
- edi, |
- edi); |
+ GenerateNumberDictionaryLoad( |
+ masm, &slow_reload_receiver, eax, ecx, ebx, edx, edi, edi); |
__ IncrementCounter(&Counters::keyed_call_generic_smi_dict, 1); |
__ jmp(&do_call); |
@@ -1459,21 +1458,14 @@ |
Immediate(Factory::hash_table_map())); |
__ j(not_equal, &lookup_monomorphic_cache, not_taken); |
- GenerateDictionaryLoad(masm, |
- &slow_load, |
- edx, |
- ecx, |
- ebx, |
- eax, |
- edi, |
- edi, |
- DICTIONARY_CHECK_DONE); |
+ GenerateDictionaryLoad( |
+ masm, &slow_load, edx, ecx, ebx, eax, edi, edi, DICTIONARY_CHECK_DONE); |
__ IncrementCounter(&Counters::keyed_call_generic_lookup_dict, 1); |
__ jmp(&do_call); |
__ bind(&lookup_monomorphic_cache); |
__ IncrementCounter(&Counters::keyed_call_generic_lookup_cache, 1); |
- GenerateMonomorphicCacheProbe(masm, argc, Code::KEYED_CALL_IC, &slow_call); |
+ GenerateMonomorphicCacheProbe(masm, argc, Code::KEYED_CALL_IC); |
// Fall through on miss. |
__ bind(&slow_call); |
@@ -1487,19 +1479,35 @@ |
GenerateMiss(masm, argc); |
__ bind(&index_string); |
- GenerateIndexFromHash(masm, ecx, ebx, &index_smi); |
+ GenerateIndexFromHash(masm, ecx, ebx); |
+ // Now jump to the place where smi keys are handled. |
+ __ jmp(&index_smi); |
} |
void KeyedCallIC::GenerateNormal(MacroAssembler* masm, int argc) { |
- Label miss; |
- GenerateCallNormal(masm, argc, &miss); |
- __ bind(&miss); |
+ // ----------- S t a t e ------------- |
+ // -- ecx : name |
+ // -- esp[0] : return address |
+ // -- esp[(argc - n) * 4] : arg[n] (zero-based) |
+ // -- ... |
+ // -- esp[(argc + 1) * 4] : receiver |
+ // ----------------------------------- |
+ |
+ GenerateCallNormal(masm, argc); |
GenerateMiss(masm, argc); |
} |
void KeyedCallIC::GenerateMiss(MacroAssembler* masm, int argc) { |
+ // ----------- S t a t e ------------- |
+ // -- ecx : name |
+ // -- esp[0] : return address |
+ // -- esp[(argc - n) * 4] : arg[n] (zero-based) |
+ // -- ... |
+ // -- esp[(argc + 1) * 4] : receiver |
+ // ----------------------------------- |
+ |
GenerateCallMiss(masm, argc, IC::kKeyedCallIC_Miss); |
} |