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

Side by Side Diff: src/ia32/ic-ia32.cc

Issue 12330012: ES6 symbols: Allow symbols as property names (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Platform ports Created 7 years, 9 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 unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « src/ia32/code-stubs-ia32.cc ('k') | src/ia32/macro-assembler-ia32.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2012 the V8 project authors. All rights reserved. 1 // Copyright 2012 the V8 project authors. All rights reserved.
2 // Redistribution and use in source and binary forms, with or without 2 // Redistribution and use in source and binary forms, with or without
3 // modification, are permitted provided that the following conditions are 3 // modification, are permitted provided that the following conditions are
4 // met: 4 // met:
5 // 5 //
6 // * Redistributions of source code must retain the above copyright 6 // * Redistributions of source code must retain the above copyright
7 // notice, this list of conditions and the following disclaimer. 7 // notice, this list of conditions and the following disclaimer.
8 // * Redistributions in binary form must reproduce the above 8 // * Redistributions in binary form must reproduce the above
9 // copyright notice, this list of conditions and the following 9 // copyright notice, this list of conditions and the following
10 // disclaimer in the documentation and/or other materials provided 10 // disclaimer in the documentation and/or other materials provided
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after
53 __ j(equal, global_object); 53 __ j(equal, global_object);
54 __ cmp(type, JS_BUILTINS_OBJECT_TYPE); 54 __ cmp(type, JS_BUILTINS_OBJECT_TYPE);
55 __ j(equal, global_object); 55 __ j(equal, global_object);
56 __ cmp(type, JS_GLOBAL_PROXY_TYPE); 56 __ cmp(type, JS_GLOBAL_PROXY_TYPE);
57 __ j(equal, global_object); 57 __ j(equal, global_object);
58 } 58 }
59 59
60 60
61 // Generated code falls through if the receiver is a regular non-global 61 // Generated code falls through if the receiver is a regular non-global
62 // JS object with slow properties and no interceptors. 62 // JS object with slow properties and no interceptors.
63 static void GenerateStringDictionaryReceiverCheck(MacroAssembler* masm, 63 static void GenerateNameDictionaryReceiverCheck(MacroAssembler* masm,
64 Register receiver, 64 Register receiver,
65 Register r0, 65 Register r0,
66 Register r1, 66 Register r1,
67 Label* miss) { 67 Label* miss) {
68 // Register usage: 68 // Register usage:
69 // receiver: holds the receiver on entry and is unchanged. 69 // receiver: holds the receiver on entry and is unchanged.
70 // r0: used to hold receiver instance type. 70 // r0: used to hold receiver instance type.
71 // Holds the property dictionary on fall through. 71 // Holds the property dictionary on fall through.
72 // r1: used to hold receivers map. 72 // r1: used to hold receivers map.
73 73
74 // Check that the receiver isn't a smi. 74 // Check that the receiver isn't a smi.
75 __ JumpIfSmi(receiver, miss); 75 __ JumpIfSmi(receiver, miss);
76 76
77 // Check that the receiver is a valid JS object. 77 // Check that the receiver is a valid JS object.
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after
120 // 120 //
121 // r0 - used for the index into the property dictionary 121 // r0 - used for the index into the property dictionary
122 // 122 //
123 // r1 - used to hold the capacity of the property dictionary. 123 // r1 - used to hold the capacity of the property dictionary.
124 // 124 //
125 // result - holds the result on exit. 125 // result - holds the result on exit.
126 126
127 Label done; 127 Label done;
128 128
129 // Probe the dictionary. 129 // Probe the dictionary.
130 StringDictionaryLookupStub::GeneratePositiveLookup(masm, 130 NameDictionaryLookupStub::GeneratePositiveLookup(masm,
131 miss_label, 131 miss_label,
132 &done, 132 &done,
133 elements, 133 elements,
134 name, 134 name,
135 r0, 135 r0,
136 r1); 136 r1);
137 137
138 // If probing finds an entry in the dictionary, r0 contains the 138 // If probing finds an entry in the dictionary, r0 contains the
139 // index into the dictionary. Check that the value is a normal 139 // index into the dictionary. Check that the value is a normal
140 // property. 140 // property.
141 __ bind(&done); 141 __ bind(&done);
142 const int kElementsStartOffset = 142 const int kElementsStartOffset =
143 StringDictionary::kHeaderSize + 143 NameDictionary::kHeaderSize +
144 StringDictionary::kElementsStartIndex * kPointerSize; 144 NameDictionary::kElementsStartIndex * kPointerSize;
145 const int kDetailsOffset = kElementsStartOffset + 2 * kPointerSize; 145 const int kDetailsOffset = kElementsStartOffset + 2 * kPointerSize;
146 __ test(Operand(elements, r0, times_4, kDetailsOffset - kHeapObjectTag), 146 __ test(Operand(elements, r0, times_4, kDetailsOffset - kHeapObjectTag),
147 Immediate(PropertyDetails::TypeField::kMask << kSmiTagSize)); 147 Immediate(PropertyDetails::TypeField::kMask << kSmiTagSize));
148 __ j(not_zero, miss_label); 148 __ j(not_zero, miss_label);
149 149
150 // Get the value at the masked, scaled index. 150 // Get the value at the masked, scaled index.
151 const int kValueOffset = kElementsStartOffset + kPointerSize; 151 const int kValueOffset = kElementsStartOffset + kPointerSize;
152 __ mov(result, Operand(elements, r0, times_4, kValueOffset - kHeapObjectTag)); 152 __ mov(result, Operand(elements, r0, times_4, kValueOffset - kHeapObjectTag));
153 } 153 }
154 154
(...skipping 20 matching lines...) Expand all
175 // 175 //
176 // value - holds the value to store and is unchanged. 176 // value - holds the value to store and is unchanged.
177 // 177 //
178 // r0 - used for index into the property dictionary and is clobbered. 178 // r0 - used for index into the property dictionary and is clobbered.
179 // 179 //
180 // r1 - used to hold the capacity of the property dictionary and is clobbered. 180 // r1 - used to hold the capacity of the property dictionary and is clobbered.
181 Label done; 181 Label done;
182 182
183 183
184 // Probe the dictionary. 184 // Probe the dictionary.
185 StringDictionaryLookupStub::GeneratePositiveLookup(masm, 185 NameDictionaryLookupStub::GeneratePositiveLookup(masm,
186 miss_label, 186 miss_label,
187 &done, 187 &done,
188 elements, 188 elements,
189 name, 189 name,
190 r0, 190 r0,
191 r1); 191 r1);
192 192
193 // If probing finds an entry in the dictionary, r0 contains the 193 // If probing finds an entry in the dictionary, r0 contains the
194 // index into the dictionary. Check that the value is a normal 194 // index into the dictionary. Check that the value is a normal
195 // property that is not read only. 195 // property that is not read only.
196 __ bind(&done); 196 __ bind(&done);
197 const int kElementsStartOffset = 197 const int kElementsStartOffset =
198 StringDictionary::kHeaderSize + 198 NameDictionary::kHeaderSize +
199 StringDictionary::kElementsStartIndex * kPointerSize; 199 NameDictionary::kElementsStartIndex * kPointerSize;
200 const int kDetailsOffset = kElementsStartOffset + 2 * kPointerSize; 200 const int kDetailsOffset = kElementsStartOffset + 2 * kPointerSize;
201 const int kTypeAndReadOnlyMask = 201 const int kTypeAndReadOnlyMask =
202 (PropertyDetails::TypeField::kMask | 202 (PropertyDetails::TypeField::kMask |
203 PropertyDetails::AttributesField::encode(READ_ONLY)) << kSmiTagSize; 203 PropertyDetails::AttributesField::encode(READ_ONLY)) << kSmiTagSize;
204 __ test(Operand(elements, r0, times_4, kDetailsOffset - kHeapObjectTag), 204 __ test(Operand(elements, r0, times_4, kDetailsOffset - kHeapObjectTag),
205 Immediate(kTypeAndReadOnlyMask)); 205 Immediate(kTypeAndReadOnlyMask));
206 __ j(not_zero, miss_label); 206 __ j(not_zero, miss_label);
207 207
208 // Store the value at the masked, scaled index. 208 // Store the value at the masked, scaled index.
209 const int kValueOffset = kElementsStartOffset + kPointerSize; 209 const int kValueOffset = kElementsStartOffset + kPointerSize;
(...skipping 75 matching lines...) Expand 10 before | Expand all | Expand 10 after
285 __ cmp(scratch, Immediate(FACTORY->the_hole_value())); 285 __ cmp(scratch, Immediate(FACTORY->the_hole_value()));
286 // In case the loaded value is the_hole we have to consult GetProperty 286 // In case the loaded value is the_hole we have to consult GetProperty
287 // to ensure the prototype chain is searched. 287 // to ensure the prototype chain is searched.
288 __ j(equal, out_of_range); 288 __ j(equal, out_of_range);
289 if (!result.is(scratch)) { 289 if (!result.is(scratch)) {
290 __ mov(result, scratch); 290 __ mov(result, scratch);
291 } 291 }
292 } 292 }
293 293
294 294
295 // Checks whether a key is an array index string or an internalized string. 295 // Checks whether a key is an array index string or a unique name.
296 // Falls through if the key is an internalized string. 296 // Falls through if the key is a unique name.
297 static void GenerateKeyStringCheck(MacroAssembler* masm, 297 static void GenerateKeyNameCheck(MacroAssembler* masm,
298 Register key, 298 Register key,
299 Register map, 299 Register map,
300 Register hash, 300 Register hash,
301 Label* index_string, 301 Label* index_string,
302 Label* not_internalized) { 302 Label* not_unique) {
303 // Register use: 303 // Register use:
304 // key - holds the key and is unchanged. Assumed to be non-smi. 304 // key - holds the key and is unchanged. Assumed to be non-smi.
305 // Scratch registers: 305 // Scratch registers:
306 // map - used to hold the map of the key. 306 // map - used to hold the map of the key.
307 // hash - used to hold the hash of the key. 307 // hash - used to hold the hash of the key.
308 __ CmpObjectType(key, FIRST_NONSTRING_TYPE, map); 308 Label unique;
309 __ j(above_equal, not_internalized); 309 __ CmpObjectType(key, LAST_UNIQUE_NAME_TYPE, map);
310 __ j(above, not_unique);
311 STATIC_ASSERT(LAST_UNIQUE_NAME_TYPE == FIRST_NONSTRING_TYPE);
312 __ j(equal, &unique);
310 313
311 // Is the string an array index, with cached numeric value? 314 // Is the string an array index, with cached numeric value?
312 __ mov(hash, FieldOperand(key, String::kHashFieldOffset)); 315 __ mov(hash, FieldOperand(key, Name::kHashFieldOffset));
313 __ test(hash, Immediate(String::kContainsCachedArrayIndexMask)); 316 __ test(hash, Immediate(Name::kContainsCachedArrayIndexMask));
314 __ j(zero, index_string); 317 __ j(zero, index_string);
315 318
316 // Is the string internalized? 319 // Is the string internalized?
317 STATIC_ASSERT(kInternalizedTag != 0); 320 STATIC_ASSERT(kInternalizedTag != 0);
318 __ test_b(FieldOperand(map, Map::kInstanceTypeOffset), kIsInternalizedMask); 321 __ test_b(FieldOperand(map, Map::kInstanceTypeOffset), kIsInternalizedMask);
319 __ j(zero, not_internalized); 322 __ j(zero, not_unique);
323
324 __ bind(&unique);
320 } 325 }
321 326
322 327
323 static Operand GenerateMappedArgumentsLookup(MacroAssembler* masm, 328 static Operand GenerateMappedArgumentsLookup(MacroAssembler* masm,
324 Register object, 329 Register object,
325 Register key, 330 Register key,
326 Register scratch1, 331 Register scratch1,
327 Register scratch2, 332 Register scratch2,
328 Label* unmapped_case, 333 Label* unmapped_case,
329 Label* slow_case) { 334 Label* slow_case) {
(...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after
396 FixedArray::kHeaderSize); 401 FixedArray::kHeaderSize);
397 } 402 }
398 403
399 404
400 void KeyedLoadIC::GenerateGeneric(MacroAssembler* masm) { 405 void KeyedLoadIC::GenerateGeneric(MacroAssembler* masm) {
401 // ----------- S t a t e ------------- 406 // ----------- S t a t e -------------
402 // -- ecx : key 407 // -- ecx : key
403 // -- edx : receiver 408 // -- edx : receiver
404 // -- esp[0] : return address 409 // -- esp[0] : return address
405 // ----------------------------------- 410 // -----------------------------------
406 Label slow, check_string, index_smi, index_string, property_array_property; 411 Label slow, check_name, index_smi, index_name, property_array_property;
407 Label probe_dictionary, check_number_dictionary; 412 Label probe_dictionary, check_number_dictionary;
408 413
409 // Check that the key is a smi. 414 // Check that the key is a smi.
410 __ JumpIfNotSmi(ecx, &check_string); 415 __ JumpIfNotSmi(ecx, &check_name);
411 __ bind(&index_smi); 416 __ bind(&index_smi);
412 // Now the key is known to be a smi. This place is also jumped to from 417 // Now the key is known to be a smi. This place is also jumped to from
413 // where a numeric string is converted to a smi. 418 // where a numeric string is converted to a smi.
414 419
415 GenerateKeyedLoadReceiverCheck( 420 GenerateKeyedLoadReceiverCheck(
416 masm, edx, eax, Map::kHasIndexedInterceptor, &slow); 421 masm, edx, eax, Map::kHasIndexedInterceptor, &slow);
417 422
418 // Check the receiver's map to see if it has fast elements. 423 // Check the receiver's map to see if it has fast elements.
419 __ CheckFastElements(eax, &check_number_dictionary); 424 __ CheckFastElements(eax, &check_number_dictionary);
420 425
(...skipping 30 matching lines...) Expand all
451 // Pop the receiver from the stack and jump to runtime. 456 // Pop the receiver from the stack and jump to runtime.
452 __ pop(edx); 457 __ pop(edx);
453 458
454 __ bind(&slow); 459 __ bind(&slow);
455 // Slow case: jump to runtime. 460 // Slow case: jump to runtime.
456 // edx: receiver 461 // edx: receiver
457 // ecx: key 462 // ecx: key
458 __ IncrementCounter(counters->keyed_load_generic_slow(), 1); 463 __ IncrementCounter(counters->keyed_load_generic_slow(), 1);
459 GenerateRuntimeGetProperty(masm); 464 GenerateRuntimeGetProperty(masm);
460 465
461 __ bind(&check_string); 466 __ bind(&check_name);
462 GenerateKeyStringCheck(masm, ecx, eax, ebx, &index_string, &slow); 467 GenerateKeyNameCheck(masm, ecx, eax, ebx, &index_name, &slow);
463 468
464 GenerateKeyedLoadReceiverCheck( 469 GenerateKeyedLoadReceiverCheck(
465 masm, edx, eax, Map::kHasNamedInterceptor, &slow); 470 masm, edx, eax, Map::kHasNamedInterceptor, &slow);
466 471
467 // If the receiver is a fast-case object, check the keyed lookup 472 // If the receiver is a fast-case object, check the keyed lookup
468 // cache. Otherwise probe the dictionary. 473 // cache. Otherwise probe the dictionary.
469 __ mov(ebx, FieldOperand(edx, JSObject::kPropertiesOffset)); 474 __ mov(ebx, FieldOperand(edx, JSObject::kPropertiesOffset));
470 __ cmp(FieldOperand(ebx, HeapObject::kMapOffset), 475 __ cmp(FieldOperand(ebx, HeapObject::kMapOffset),
471 Immediate(isolate->factory()->hash_table_map())); 476 Immediate(isolate->factory()->hash_table_map()));
472 __ j(equal, &probe_dictionary); 477 __ j(equal, &probe_dictionary);
(...skipping 88 matching lines...) Expand 10 before | Expand all | Expand 10 after
561 __ bind(&probe_dictionary); 566 __ bind(&probe_dictionary);
562 567
563 __ mov(eax, FieldOperand(edx, JSObject::kMapOffset)); 568 __ mov(eax, FieldOperand(edx, JSObject::kMapOffset));
564 __ movzx_b(eax, FieldOperand(eax, Map::kInstanceTypeOffset)); 569 __ movzx_b(eax, FieldOperand(eax, Map::kInstanceTypeOffset));
565 GenerateGlobalInstanceTypeCheck(masm, eax, &slow); 570 GenerateGlobalInstanceTypeCheck(masm, eax, &slow);
566 571
567 GenerateDictionaryLoad(masm, &slow, ebx, ecx, eax, edi, eax); 572 GenerateDictionaryLoad(masm, &slow, ebx, ecx, eax, edi, eax);
568 __ IncrementCounter(counters->keyed_load_generic_symbol(), 1); 573 __ IncrementCounter(counters->keyed_load_generic_symbol(), 1);
569 __ ret(0); 574 __ ret(0);
570 575
571 __ bind(&index_string); 576 __ bind(&index_name);
572 __ IndexFromHash(ebx, ecx); 577 __ IndexFromHash(ebx, ecx);
573 // Now jump to the place where smi keys are handled. 578 // Now jump to the place where smi keys are handled.
574 __ jmp(&index_smi); 579 __ jmp(&index_smi);
575 } 580 }
576 581
577 582
578 void KeyedLoadIC::GenerateString(MacroAssembler* masm) { 583 void KeyedLoadIC::GenerateString(MacroAssembler* masm) {
579 // ----------- S t a t e ------------- 584 // ----------- S t a t e -------------
580 // -- ecx : key (index) 585 // -- ecx : key (index)
581 // -- edx : receiver 586 // -- edx : receiver
(...skipping 427 matching lines...) Expand 10 before | Expand all | Expand 10 after
1009 // -- esp[0] : return address 1014 // -- esp[0] : return address
1010 // -- esp[(argc - n) * 4] : arg[n] (zero-based) 1015 // -- esp[(argc - n) * 4] : arg[n] (zero-based)
1011 // -- ... 1016 // -- ...
1012 // -- esp[(argc + 1) * 4] : receiver 1017 // -- esp[(argc + 1) * 4] : receiver
1013 // ----------------------------------- 1018 // -----------------------------------
1014 Label miss; 1019 Label miss;
1015 1020
1016 // Get the receiver of the function from the stack; 1 ~ return address. 1021 // Get the receiver of the function from the stack; 1 ~ return address.
1017 __ mov(edx, Operand(esp, (argc + 1) * kPointerSize)); 1022 __ mov(edx, Operand(esp, (argc + 1) * kPointerSize));
1018 1023
1019 GenerateStringDictionaryReceiverCheck(masm, edx, eax, ebx, &miss); 1024 GenerateNameDictionaryReceiverCheck(masm, edx, eax, ebx, &miss);
1020 1025
1021 // eax: elements 1026 // eax: elements
1022 // Search the dictionary placing the result in edi. 1027 // Search the dictionary placing the result in edi.
1023 GenerateDictionaryLoad(masm, &miss, eax, ecx, edi, ebx, edi); 1028 GenerateDictionaryLoad(masm, &miss, eax, ecx, edi, ebx, edi);
1024 GenerateFunctionTailCall(masm, argc, &miss); 1029 GenerateFunctionTailCall(masm, argc, &miss);
1025 1030
1026 __ bind(&miss); 1031 __ bind(&miss);
1027 } 1032 }
1028 1033
1029 1034
(...skipping 95 matching lines...) Expand 10 before | Expand all | Expand 10 after
1125 // -- esp[0] : return address 1130 // -- esp[0] : return address
1126 // -- esp[(argc - n) * 4] : arg[n] (zero-based) 1131 // -- esp[(argc - n) * 4] : arg[n] (zero-based)
1127 // -- ... 1132 // -- ...
1128 // -- esp[(argc + 1) * 4] : receiver 1133 // -- esp[(argc + 1) * 4] : receiver
1129 // ----------------------------------- 1134 // -----------------------------------
1130 1135
1131 // Get the receiver of the function from the stack; 1 ~ return address. 1136 // Get the receiver of the function from the stack; 1 ~ return address.
1132 __ mov(edx, Operand(esp, (argc + 1) * kPointerSize)); 1137 __ mov(edx, Operand(esp, (argc + 1) * kPointerSize));
1133 1138
1134 Label do_call, slow_call, slow_load, slow_reload_receiver; 1139 Label do_call, slow_call, slow_load, slow_reload_receiver;
1135 Label check_number_dictionary, check_string, lookup_monomorphic_cache; 1140 Label check_number_dictionary, check_name, lookup_monomorphic_cache;
1136 Label index_smi, index_string; 1141 Label index_smi, index_name;
1137 1142
1138 // Check that the key is a smi. 1143 // Check that the key is a smi.
1139 __ JumpIfNotSmi(ecx, &check_string); 1144 __ JumpIfNotSmi(ecx, &check_name);
1140 1145
1141 __ bind(&index_smi); 1146 __ bind(&index_smi);
1142 // Now the key is known to be a smi. This place is also jumped to from 1147 // Now the key is known to be a smi. This place is also jumped to from
1143 // where a numeric string is converted to a smi. 1148 // where a numeric string is converted to a smi.
1144 1149
1145 GenerateKeyedLoadReceiverCheck( 1150 GenerateKeyedLoadReceiverCheck(
1146 masm, edx, eax, Map::kHasIndexedInterceptor, &slow_call); 1151 masm, edx, eax, Map::kHasIndexedInterceptor, &slow_call);
1147 1152
1148 GenerateFastArrayLoad( 1153 GenerateFastArrayLoad(
1149 masm, edx, ecx, eax, edi, &check_number_dictionary, &slow_load); 1154 masm, edx, ecx, eax, edi, &check_number_dictionary, &slow_load);
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after
1188 __ push(edx); // pass the receiver 1193 __ push(edx); // pass the receiver
1189 __ push(ecx); // pass the key 1194 __ push(ecx); // pass the key
1190 __ CallRuntime(Runtime::kKeyedGetProperty, 2); 1195 __ CallRuntime(Runtime::kKeyedGetProperty, 2);
1191 __ pop(ecx); // restore the key 1196 __ pop(ecx); // restore the key
1192 // Leave the internal frame. 1197 // Leave the internal frame.
1193 } 1198 }
1194 1199
1195 __ mov(edi, eax); 1200 __ mov(edi, eax);
1196 __ jmp(&do_call); 1201 __ jmp(&do_call);
1197 1202
1198 __ bind(&check_string); 1203 __ bind(&check_name);
1199 GenerateKeyStringCheck(masm, ecx, eax, ebx, &index_string, &slow_call); 1204 GenerateKeyNameCheck(masm, ecx, eax, ebx, &index_name, &slow_call);
1200 1205
1201 // The key is known to be an internalized string. 1206 // The key is known to be a unique name.
1202 // If the receiver is a regular JS object with slow properties then do 1207 // If the receiver is a regular JS object with slow properties then do
1203 // a quick inline probe of the receiver's dictionary. 1208 // a quick inline probe of the receiver's dictionary.
1204 // Otherwise do the monomorphic cache probe. 1209 // Otherwise do the monomorphic cache probe.
1205 GenerateKeyedLoadReceiverCheck( 1210 GenerateKeyedLoadReceiverCheck(
1206 masm, edx, eax, Map::kHasNamedInterceptor, &lookup_monomorphic_cache); 1211 masm, edx, eax, Map::kHasNamedInterceptor, &lookup_monomorphic_cache);
1207 1212
1208 __ mov(ebx, FieldOperand(edx, JSObject::kPropertiesOffset)); 1213 __ mov(ebx, FieldOperand(edx, JSObject::kPropertiesOffset));
1209 __ CheckMap(ebx, 1214 __ CheckMap(ebx,
1210 isolate->factory()->hash_table_map(), 1215 isolate->factory()->hash_table_map(),
1211 &lookup_monomorphic_cache, 1216 &lookup_monomorphic_cache,
1212 DONT_DO_SMI_CHECK); 1217 DONT_DO_SMI_CHECK);
1213 1218
1214 GenerateDictionaryLoad(masm, &slow_load, ebx, ecx, eax, edi, edi); 1219 GenerateDictionaryLoad(masm, &slow_load, ebx, ecx, eax, edi, edi);
1215 __ IncrementCounter(counters->keyed_call_generic_lookup_dict(), 1); 1220 __ IncrementCounter(counters->keyed_call_generic_lookup_dict(), 1);
1216 __ jmp(&do_call); 1221 __ jmp(&do_call);
1217 1222
1218 __ bind(&lookup_monomorphic_cache); 1223 __ bind(&lookup_monomorphic_cache);
1219 __ IncrementCounter(counters->keyed_call_generic_lookup_cache(), 1); 1224 __ IncrementCounter(counters->keyed_call_generic_lookup_cache(), 1);
1220 CallICBase::GenerateMonomorphicCacheProbe(masm, argc, Code::KEYED_CALL_IC, 1225 CallICBase::GenerateMonomorphicCacheProbe(masm, argc, Code::KEYED_CALL_IC,
1221 Code::kNoExtraICState); 1226 Code::kNoExtraICState);
1222 // Fall through on miss. 1227 // Fall through on miss.
1223 1228
1224 __ bind(&slow_call); 1229 __ bind(&slow_call);
1225 // This branch is taken if: 1230 // This branch is taken if:
1226 // - the receiver requires boxing or access check, 1231 // - the receiver requires boxing or access check,
1227 // - the key is neither smi nor an internalized string, 1232 // - the key is neither smi nor a unique name,
1228 // - the value loaded is not a function, 1233 // - the value loaded is not a function,
1229 // - there is hope that the runtime will create a monomorphic call stub 1234 // - there is hope that the runtime will create a monomorphic call stub
1230 // that will get fetched next time. 1235 // that will get fetched next time.
1231 __ IncrementCounter(counters->keyed_call_generic_slow(), 1); 1236 __ IncrementCounter(counters->keyed_call_generic_slow(), 1);
1232 GenerateMiss(masm, argc); 1237 GenerateMiss(masm, argc);
1233 1238
1234 __ bind(&index_string); 1239 __ bind(&index_name);
1235 __ IndexFromHash(ebx, ecx); 1240 __ IndexFromHash(ebx, ecx);
1236 // Now jump to the place where smi keys are handled. 1241 // Now jump to the place where smi keys are handled.
1237 __ jmp(&index_smi); 1242 __ jmp(&index_smi);
1238 } 1243 }
1239 1244
1240 1245
1241 void KeyedCallIC::GenerateNonStrictArguments(MacroAssembler* masm, 1246 void KeyedCallIC::GenerateNonStrictArguments(MacroAssembler* masm,
1242 int argc) { 1247 int argc) {
1243 // ----------- S t a t e ------------- 1248 // ----------- S t a t e -------------
1244 // -- ecx : name 1249 // -- ecx : name
(...skipping 24 matching lines...) Expand all
1269 1274
1270 void KeyedCallIC::GenerateNormal(MacroAssembler* masm, int argc) { 1275 void KeyedCallIC::GenerateNormal(MacroAssembler* masm, int argc) {
1271 // ----------- S t a t e ------------- 1276 // ----------- S t a t e -------------
1272 // -- ecx : name 1277 // -- ecx : name
1273 // -- esp[0] : return address 1278 // -- esp[0] : return address
1274 // -- esp[(argc - n) * 4] : arg[n] (zero-based) 1279 // -- esp[(argc - n) * 4] : arg[n] (zero-based)
1275 // -- ... 1280 // -- ...
1276 // -- esp[(argc + 1) * 4] : receiver 1281 // -- esp[(argc + 1) * 4] : receiver
1277 // ----------------------------------- 1282 // -----------------------------------
1278 1283
1279 // Check if the name is a string. 1284 // Check if the name is really a name.
1280 Label miss; 1285 Label miss;
1281 __ JumpIfSmi(ecx, &miss); 1286 __ JumpIfSmi(ecx, &miss);
1282 Condition cond = masm->IsObjectStringType(ecx, eax, eax); 1287 Condition cond = masm->IsObjectNameType(ecx, eax, eax);
1283 __ j(NegateCondition(cond), &miss); 1288 __ j(NegateCondition(cond), &miss);
1284 CallICBase::GenerateNormal(masm, argc); 1289 CallICBase::GenerateNormal(masm, argc);
1285 __ bind(&miss); 1290 __ bind(&miss);
1286 GenerateMiss(masm, argc); 1291 GenerateMiss(masm, argc);
1287 } 1292 }
1288 1293
1289 1294
1290 void LoadIC::GenerateMegamorphic(MacroAssembler* masm) { 1295 void LoadIC::GenerateMegamorphic(MacroAssembler* masm) {
1291 // ----------- S t a t e ------------- 1296 // ----------- S t a t e -------------
1292 // -- ecx : name 1297 // -- ecx : name
(...skipping 12 matching lines...) Expand all
1305 1310
1306 1311
1307 void LoadIC::GenerateNormal(MacroAssembler* masm) { 1312 void LoadIC::GenerateNormal(MacroAssembler* masm) {
1308 // ----------- S t a t e ------------- 1313 // ----------- S t a t e -------------
1309 // -- ecx : name 1314 // -- ecx : name
1310 // -- edx : receiver 1315 // -- edx : receiver
1311 // -- esp[0] : return address 1316 // -- esp[0] : return address
1312 // ----------------------------------- 1317 // -----------------------------------
1313 Label miss; 1318 Label miss;
1314 1319
1315 GenerateStringDictionaryReceiverCheck(masm, edx, eax, ebx, &miss); 1320 GenerateNameDictionaryReceiverCheck(masm, edx, eax, ebx, &miss);
1316 1321
1317 // eax: elements 1322 // eax: elements
1318 // Search the dictionary placing the result in eax. 1323 // Search the dictionary placing the result in eax.
1319 GenerateDictionaryLoad(masm, &miss, eax, ecx, edi, ebx, eax); 1324 GenerateDictionaryLoad(masm, &miss, eax, ecx, edi, ebx, eax);
1320 __ ret(0); 1325 __ ret(0);
1321 1326
1322 // Cache miss: Jump to runtime. 1327 // Cache miss: Jump to runtime.
1323 __ bind(&miss); 1328 __ bind(&miss);
1324 GenerateMiss(masm); 1329 GenerateMiss(masm);
1325 } 1330 }
(...skipping 103 matching lines...) Expand 10 before | Expand all | Expand 10 after
1429 void StoreIC::GenerateNormal(MacroAssembler* masm) { 1434 void StoreIC::GenerateNormal(MacroAssembler* masm) {
1430 // ----------- S t a t e ------------- 1435 // ----------- S t a t e -------------
1431 // -- eax : value 1436 // -- eax : value
1432 // -- ecx : name 1437 // -- ecx : name
1433 // -- edx : receiver 1438 // -- edx : receiver
1434 // -- esp[0] : return address 1439 // -- esp[0] : return address
1435 // ----------------------------------- 1440 // -----------------------------------
1436 1441
1437 Label miss, restore_miss; 1442 Label miss, restore_miss;
1438 1443
1439 GenerateStringDictionaryReceiverCheck(masm, edx, ebx, edi, &miss); 1444 GenerateNameDictionaryReceiverCheck(masm, edx, ebx, edi, &miss);
1440 1445
1441 // A lot of registers are needed for storing to slow case 1446 // A lot of registers are needed for storing to slow case
1442 // objects. Push and restore receiver but rely on 1447 // objects. Push and restore receiver but rely on
1443 // GenerateDictionaryStore preserving the value and name. 1448 // GenerateDictionaryStore preserving the value and name.
1444 __ push(edx); 1449 __ push(edx);
1445 GenerateDictionaryStore(masm, &restore_miss, ebx, ecx, eax, edx, edi); 1450 GenerateDictionaryStore(masm, &restore_miss, ebx, ecx, eax, edx, edi);
1446 __ Drop(1); 1451 __ Drop(1);
1447 Counters* counters = masm->isolate()->counters(); 1452 Counters* counters = masm->isolate()->counters();
1448 __ IncrementCounter(counters->store_normal_hit(), 1); 1453 __ IncrementCounter(counters->store_normal_hit(), 1);
1449 __ ret(0); 1454 __ ret(0);
(...skipping 215 matching lines...) Expand 10 before | Expand all | Expand 10 after
1665 Condition cc = (check == ENABLE_INLINED_SMI_CHECK) 1670 Condition cc = (check == ENABLE_INLINED_SMI_CHECK)
1666 ? (*jmp_address == Assembler::kJncShortOpcode ? not_zero : zero) 1671 ? (*jmp_address == Assembler::kJncShortOpcode ? not_zero : zero)
1667 : (*jmp_address == Assembler::kJnzShortOpcode ? not_carry : carry); 1672 : (*jmp_address == Assembler::kJnzShortOpcode ? not_carry : carry);
1668 *jmp_address = static_cast<byte>(Assembler::kJccShortPrefix | cc); 1673 *jmp_address = static_cast<byte>(Assembler::kJccShortPrefix | cc);
1669 } 1674 }
1670 1675
1671 1676
1672 } } // namespace v8::internal 1677 } } // namespace v8::internal
1673 1678
1674 #endif // V8_TARGET_ARCH_IA32 1679 #endif // V8_TARGET_ARCH_IA32
OLDNEW
« no previous file with comments | « src/ia32/code-stubs-ia32.cc ('k') | src/ia32/macro-assembler-ia32.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698