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

Side by Side Diff: src/x64/ic-x64.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/x64/code-stubs-x64.cc ('k') | src/x64/macro-assembler-x64.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 __ cmpb(type, Immediate(JS_BUILTINS_OBJECT_TYPE)); 54 __ cmpb(type, Immediate(JS_BUILTINS_OBJECT_TYPE));
55 __ j(equal, global_object); 55 __ j(equal, global_object);
56 __ cmpb(type, Immediate(JS_GLOBAL_PROXY_TYPE)); 56 __ cmpb(type, Immediate(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 __ JumpIfSmi(receiver, miss); 74 __ JumpIfSmi(receiver, miss);
75 75
76 // Check that the receiver is a valid JS object. 76 // Check that the receiver is a valid JS object.
77 __ movq(r1, FieldOperand(receiver, HeapObject::kMapOffset)); 77 __ movq(r1, FieldOperand(receiver, HeapObject::kMapOffset));
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after
120 // 120 //
121 // r0 - used to hold the capacity of the property dictionary. 121 // r0 - used to hold the capacity of the property dictionary.
122 // 122 //
123 // r1 - used to hold the index into the property dictionary. 123 // r1 - used to hold the index into the property dictionary.
124 // 124 //
125 // result - holds the result on exit if the load succeeded. 125 // result - holds the result on exit if the load succeeded.
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, r1 contains the 138 // If probing finds an entry in the dictionary, r1 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, r1, times_pointer_size, 146 __ Test(Operand(elements, r1, times_pointer_size,
147 kDetailsOffset - kHeapObjectTag), 147 kDetailsOffset - kHeapObjectTag),
148 Smi::FromInt(PropertyDetails::TypeField::kMask)); 148 Smi::FromInt(PropertyDetails::TypeField::kMask));
149 __ j(not_zero, miss_label); 149 __ j(not_zero, miss_label);
150 150
151 // Get the value at the masked, scaled index. 151 // Get the value at the masked, scaled index.
152 const int kValueOffset = kElementsStartOffset + kPointerSize; 152 const int kValueOffset = kElementsStartOffset + kPointerSize;
153 __ movq(result, 153 __ movq(result,
154 Operand(elements, r1, times_pointer_size, 154 Operand(elements, r1, times_pointer_size,
(...skipping 22 matching lines...) Expand all
177 // name - holds the name of the property on entry and is unchanged. 177 // name - holds the name of the property on entry and is unchanged.
178 // 178 //
179 // value - holds the value to store and is unchanged. 179 // value - holds the value to store and is unchanged.
180 // 180 //
181 // scratch0 - used during the positive dictionary lookup and is clobbered. 181 // scratch0 - used during the positive dictionary lookup and is clobbered.
182 // 182 //
183 // scratch1 - used for index into the property dictionary and is clobbered. 183 // scratch1 - used for index into the property dictionary and is clobbered.
184 Label done; 184 Label done;
185 185
186 // Probe the dictionary. 186 // Probe the dictionary.
187 StringDictionaryLookupStub::GeneratePositiveLookup(masm, 187 NameDictionaryLookupStub::GeneratePositiveLookup(masm,
188 miss_label, 188 miss_label,
189 &done, 189 &done,
190 elements, 190 elements,
191 name, 191 name,
192 scratch0, 192 scratch0,
193 scratch1); 193 scratch1);
194 194
195 // If probing finds an entry in the dictionary, scratch0 contains the 195 // If probing finds an entry in the dictionary, scratch0 contains the
196 // index into the dictionary. Check that the value is a normal 196 // index into the dictionary. Check that the value is a normal
197 // property that is not read only. 197 // property that is not read only.
198 __ bind(&done); 198 __ bind(&done);
199 const int kElementsStartOffset = 199 const int kElementsStartOffset =
200 StringDictionary::kHeaderSize + 200 NameDictionary::kHeaderSize +
201 StringDictionary::kElementsStartIndex * kPointerSize; 201 NameDictionary::kElementsStartIndex * kPointerSize;
202 const int kDetailsOffset = kElementsStartOffset + 2 * kPointerSize; 202 const int kDetailsOffset = kElementsStartOffset + 2 * kPointerSize;
203 const int kTypeAndReadOnlyMask = 203 const int kTypeAndReadOnlyMask =
204 (PropertyDetails::TypeField::kMask | 204 (PropertyDetails::TypeField::kMask |
205 PropertyDetails::AttributesField::encode(READ_ONLY)) << kSmiTagSize; 205 PropertyDetails::AttributesField::encode(READ_ONLY)) << kSmiTagSize;
206 __ Test(Operand(elements, 206 __ Test(Operand(elements,
207 scratch1, 207 scratch1,
208 times_pointer_size, 208 times_pointer_size,
209 kDetailsOffset - kHeapObjectTag), 209 kDetailsOffset - kHeapObjectTag),
210 Smi::FromInt(kTypeAndReadOnlyMask)); 210 Smi::FromInt(kTypeAndReadOnlyMask));
211 __ j(not_zero, miss_label); 211 __ j(not_zero, miss_label);
(...skipping 94 matching lines...) Expand 10 before | Expand all | Expand 10 after
306 __ CompareRoot(scratch, Heap::kTheHoleValueRootIndex); 306 __ CompareRoot(scratch, Heap::kTheHoleValueRootIndex);
307 // In case the loaded value is the_hole we have to consult GetProperty 307 // In case the loaded value is the_hole we have to consult GetProperty
308 // to ensure the prototype chain is searched. 308 // to ensure the prototype chain is searched.
309 __ j(equal, out_of_range); 309 __ j(equal, out_of_range);
310 if (!result.is(scratch)) { 310 if (!result.is(scratch)) {
311 __ movq(result, scratch); 311 __ movq(result, scratch);
312 } 312 }
313 } 313 }
314 314
315 315
316 // Checks whether a key is an array index string or an internalized string. 316 // Checks whether a key is an array index string or a unique name.
317 // Falls through if the key is an internalized string. 317 // Falls through if the key is a unique name.
318 static void GenerateKeyStringCheck(MacroAssembler* masm, 318 static void GenerateKeyNameCheck(MacroAssembler* masm,
319 Register key, 319 Register key,
320 Register map, 320 Register map,
321 Register hash, 321 Register hash,
322 Label* index_string, 322 Label* index_string,
323 Label* not_internalized) { 323 Label* not_unique) {
324 // Register use: 324 // Register use:
325 // key - holds the key and is unchanged. Assumed to be non-smi. 325 // key - holds the key and is unchanged. Assumed to be non-smi.
326 // Scratch registers: 326 // Scratch registers:
327 // map - used to hold the map of the key. 327 // map - used to hold the map of the key.
328 // hash - used to hold the hash of the key. 328 // hash - used to hold the hash of the key.
329 __ CmpObjectType(key, FIRST_NONSTRING_TYPE, map); 329 Label unique;
330 __ j(above_equal, not_internalized); 330 __ CmpObjectType(key, LAST_UNIQUE_NAME_TYPE, map);
331 __ j(above, not_unique);
332 STATIC_ASSERT(LAST_UNIQUE_NAME_TYPE == FIRST_NONSTRING_TYPE);
333 __ j(equal, &unique);
334
331 // Is the string an array index, with cached numeric value? 335 // Is the string an array index, with cached numeric value?
332 __ movl(hash, FieldOperand(key, String::kHashFieldOffset)); 336 __ movl(hash, FieldOperand(key, Name::kHashFieldOffset));
333 __ testl(hash, Immediate(String::kContainsCachedArrayIndexMask)); 337 __ testl(hash, Immediate(Name::kContainsCachedArrayIndexMask));
334 __ j(zero, index_string); // The value in hash is used at jump target. 338 __ j(zero, index_string); // The value in hash is used at jump target.
335 339
336 // Is the string internalized? 340 // Is the string internalized?
337 STATIC_ASSERT(kInternalizedTag != 0); 341 STATIC_ASSERT(kInternalizedTag != 0);
338 __ testb(FieldOperand(map, Map::kInstanceTypeOffset), 342 __ testb(FieldOperand(map, Map::kInstanceTypeOffset),
339 Immediate(kIsInternalizedMask)); 343 Immediate(kIsInternalizedMask));
340 __ j(zero, not_internalized); 344 __ j(zero, not_unique);
345
346 __ bind(&unique);
341 } 347 }
342 348
343 349
344 350
345 void KeyedLoadIC::GenerateGeneric(MacroAssembler* masm) { 351 void KeyedLoadIC::GenerateGeneric(MacroAssembler* masm) {
346 // ----------- S t a t e ------------- 352 // ----------- S t a t e -------------
347 // -- rax : key 353 // -- rax : key
348 // -- rdx : receiver 354 // -- rdx : receiver
349 // -- rsp[0] : return address 355 // -- rsp[0] : return address
350 // ----------------------------------- 356 // -----------------------------------
351 Label slow, check_string, index_smi, index_string, property_array_property; 357 Label slow, check_name, index_smi, index_name, property_array_property;
352 Label probe_dictionary, check_number_dictionary; 358 Label probe_dictionary, check_number_dictionary;
353 359
354 // Check that the key is a smi. 360 // Check that the key is a smi.
355 __ JumpIfNotSmi(rax, &check_string); 361 __ JumpIfNotSmi(rax, &check_name);
356 __ bind(&index_smi); 362 __ bind(&index_smi);
357 // Now the key is known to be a smi. This place is also jumped to from below 363 // Now the key is known to be a smi. This place is also jumped to from below
358 // where a numeric string is converted to a smi. 364 // where a numeric string is converted to a smi.
359 365
360 GenerateKeyedLoadReceiverCheck( 366 GenerateKeyedLoadReceiverCheck(
361 masm, rdx, rcx, Map::kHasIndexedInterceptor, &slow); 367 masm, rdx, rcx, Map::kHasIndexedInterceptor, &slow);
362 368
363 // Check the receiver's map to see if it has fast elements. 369 // Check the receiver's map to see if it has fast elements.
364 __ CheckFastElements(rcx, &check_number_dictionary); 370 __ CheckFastElements(rcx, &check_number_dictionary);
365 371
(...skipping 24 matching lines...) Expand all
390 __ LoadFromNumberDictionary(&slow, rcx, rax, rbx, r9, rdi, rax); 396 __ LoadFromNumberDictionary(&slow, rcx, rax, rbx, r9, rdi, rax);
391 __ ret(0); 397 __ ret(0);
392 398
393 __ bind(&slow); 399 __ bind(&slow);
394 // Slow case: Jump to runtime. 400 // Slow case: Jump to runtime.
395 // rdx: receiver 401 // rdx: receiver
396 // rax: key 402 // rax: key
397 __ IncrementCounter(counters->keyed_load_generic_slow(), 1); 403 __ IncrementCounter(counters->keyed_load_generic_slow(), 1);
398 GenerateRuntimeGetProperty(masm); 404 GenerateRuntimeGetProperty(masm);
399 405
400 __ bind(&check_string); 406 __ bind(&check_name);
401 GenerateKeyStringCheck(masm, rax, rcx, rbx, &index_string, &slow); 407 GenerateKeyNameCheck(masm, rax, rcx, rbx, &index_name, &slow);
402 408
403 GenerateKeyedLoadReceiverCheck( 409 GenerateKeyedLoadReceiverCheck(
404 masm, rdx, rcx, Map::kHasNamedInterceptor, &slow); 410 masm, rdx, rcx, Map::kHasNamedInterceptor, &slow);
405 411
406 // If the receiver is a fast-case object, check the keyed lookup 412 // If the receiver is a fast-case object, check the keyed lookup
407 // cache. Otherwise probe the dictionary leaving result in rcx. 413 // cache. Otherwise probe the dictionary leaving result in rcx.
408 __ movq(rbx, FieldOperand(rdx, JSObject::kPropertiesOffset)); 414 __ movq(rbx, FieldOperand(rdx, JSObject::kPropertiesOffset));
409 __ CompareRoot(FieldOperand(rbx, HeapObject::kMapOffset), 415 __ CompareRoot(FieldOperand(rbx, HeapObject::kMapOffset),
410 Heap::kHashTableMapRootIndex); 416 Heap::kHashTableMapRootIndex);
411 __ j(equal, &probe_dictionary); 417 __ j(equal, &probe_dictionary);
(...skipping 80 matching lines...) Expand 10 before | Expand all | Expand 10 after
492 // rbx: elements 498 // rbx: elements
493 499
494 __ movq(rcx, FieldOperand(rdx, JSObject::kMapOffset)); 500 __ movq(rcx, FieldOperand(rdx, JSObject::kMapOffset));
495 __ movb(rcx, FieldOperand(rcx, Map::kInstanceTypeOffset)); 501 __ movb(rcx, FieldOperand(rcx, Map::kInstanceTypeOffset));
496 GenerateGlobalInstanceTypeCheck(masm, rcx, &slow); 502 GenerateGlobalInstanceTypeCheck(masm, rcx, &slow);
497 503
498 GenerateDictionaryLoad(masm, &slow, rbx, rax, rcx, rdi, rax); 504 GenerateDictionaryLoad(masm, &slow, rbx, rax, rcx, rdi, rax);
499 __ IncrementCounter(counters->keyed_load_generic_symbol(), 1); 505 __ IncrementCounter(counters->keyed_load_generic_symbol(), 1);
500 __ ret(0); 506 __ ret(0);
501 507
502 __ bind(&index_string); 508 __ bind(&index_name);
503 __ IndexFromHash(rbx, rax); 509 __ IndexFromHash(rbx, rax);
504 __ jmp(&index_smi); 510 __ jmp(&index_smi);
505 } 511 }
506 512
507 513
508 void KeyedLoadIC::GenerateString(MacroAssembler* masm) { 514 void KeyedLoadIC::GenerateString(MacroAssembler* masm) {
509 // ----------- S t a t e ------------- 515 // ----------- S t a t e -------------
510 // -- rax : key 516 // -- rax : key
511 // -- rdx : receiver 517 // -- rdx : receiver
512 // -- rsp[0] : return address 518 // -- rsp[0] : return address
(...skipping 380 matching lines...) Expand 10 before | Expand all | Expand 10 after
893 // rsp[16] : argument argc - 1 899 // rsp[16] : argument argc - 1
894 // ... 900 // ...
895 // rsp[argc * 8] : argument 1 901 // rsp[argc * 8] : argument 1
896 // rsp[(argc + 1) * 8] : argument 0 = receiver 902 // rsp[(argc + 1) * 8] : argument 0 = receiver
897 // ----------------------------------- 903 // -----------------------------------
898 Label miss; 904 Label miss;
899 905
900 // Get the receiver of the function from the stack. 906 // Get the receiver of the function from the stack.
901 __ movq(rdx, Operand(rsp, (argc + 1) * kPointerSize)); 907 __ movq(rdx, Operand(rsp, (argc + 1) * kPointerSize));
902 908
903 GenerateStringDictionaryReceiverCheck(masm, rdx, rax, rbx, &miss); 909 GenerateNameDictionaryReceiverCheck(masm, rdx, rax, rbx, &miss);
904 910
905 // rax: elements 911 // rax: elements
906 // Search the dictionary placing the result in rdi. 912 // Search the dictionary placing the result in rdi.
907 GenerateDictionaryLoad(masm, &miss, rax, rcx, rbx, rdi, rdi); 913 GenerateDictionaryLoad(masm, &miss, rax, rcx, rbx, rdi, rdi);
908 914
909 GenerateFunctionTailCall(masm, argc, &miss); 915 GenerateFunctionTailCall(masm, argc, &miss);
910 916
911 __ bind(&miss); 917 __ bind(&miss);
912 } 918 }
913 919
(...skipping 99 matching lines...) Expand 10 before | Expand all | Expand 10 after
1013 // rsp[16] : argument argc - 1 1019 // rsp[16] : argument argc - 1
1014 // ... 1020 // ...
1015 // rsp[argc * 8] : argument 1 1021 // rsp[argc * 8] : argument 1
1016 // rsp[(argc + 1) * 8] : argument 0 = receiver 1022 // rsp[(argc + 1) * 8] : argument 0 = receiver
1017 // ----------------------------------- 1023 // -----------------------------------
1018 1024
1019 // Get the receiver of the function from the stack; 1 ~ return address. 1025 // Get the receiver of the function from the stack; 1 ~ return address.
1020 __ movq(rdx, Operand(rsp, (argc + 1) * kPointerSize)); 1026 __ movq(rdx, Operand(rsp, (argc + 1) * kPointerSize));
1021 1027
1022 Label do_call, slow_call, slow_load; 1028 Label do_call, slow_call, slow_load;
1023 Label check_number_dictionary, check_string, lookup_monomorphic_cache; 1029 Label check_number_dictionary, check_name, lookup_monomorphic_cache;
1024 Label index_smi, index_string; 1030 Label index_smi, index_name;
1025 1031
1026 // Check that the key is a smi. 1032 // Check that the key is a smi.
1027 __ JumpIfNotSmi(rcx, &check_string); 1033 __ JumpIfNotSmi(rcx, &check_name);
1028 1034
1029 __ bind(&index_smi); 1035 __ bind(&index_smi);
1030 // Now the key is known to be a smi. This place is also jumped to from below 1036 // Now the key is known to be a smi. This place is also jumped to from below
1031 // where a numeric string is converted to a smi. 1037 // where a numeric string is converted to a smi.
1032 1038
1033 GenerateKeyedLoadReceiverCheck( 1039 GenerateKeyedLoadReceiverCheck(
1034 masm, rdx, rax, Map::kHasIndexedInterceptor, &slow_call); 1040 masm, rdx, rax, Map::kHasIndexedInterceptor, &slow_call);
1035 1041
1036 GenerateFastArrayLoad( 1042 GenerateFastArrayLoad(
1037 masm, rdx, rcx, rax, rbx, rdi, &check_number_dictionary, &slow_load); 1043 masm, rdx, rcx, rax, rbx, rdi, &check_number_dictionary, &slow_load);
(...skipping 27 matching lines...) Expand all
1065 FrameScope scope(masm, StackFrame::INTERNAL); 1071 FrameScope scope(masm, StackFrame::INTERNAL);
1066 __ push(rcx); // save the key 1072 __ push(rcx); // save the key
1067 __ push(rdx); // pass the receiver 1073 __ push(rdx); // pass the receiver
1068 __ push(rcx); // pass the key 1074 __ push(rcx); // pass the key
1069 __ CallRuntime(Runtime::kKeyedGetProperty, 2); 1075 __ CallRuntime(Runtime::kKeyedGetProperty, 2);
1070 __ pop(rcx); // restore the key 1076 __ pop(rcx); // restore the key
1071 } 1077 }
1072 __ movq(rdi, rax); 1078 __ movq(rdi, rax);
1073 __ jmp(&do_call); 1079 __ jmp(&do_call);
1074 1080
1075 __ bind(&check_string); 1081 __ bind(&check_name);
1076 GenerateKeyStringCheck(masm, rcx, rax, rbx, &index_string, &slow_call); 1082 GenerateKeyNameCheck(masm, rcx, rax, rbx, &index_name, &slow_call);
1077 1083
1078 // The key is known to be an internalized string. 1084 // The key is known to be a unique name.
1079 // If the receiver is a regular JS object with slow properties then do 1085 // If the receiver is a regular JS object with slow properties then do
1080 // a quick inline probe of the receiver's dictionary. 1086 // a quick inline probe of the receiver's dictionary.
1081 // Otherwise do the monomorphic cache probe. 1087 // Otherwise do the monomorphic cache probe.
1082 GenerateKeyedLoadReceiverCheck( 1088 GenerateKeyedLoadReceiverCheck(
1083 masm, rdx, rax, Map::kHasNamedInterceptor, &lookup_monomorphic_cache); 1089 masm, rdx, rax, Map::kHasNamedInterceptor, &lookup_monomorphic_cache);
1084 1090
1085 __ movq(rbx, FieldOperand(rdx, JSObject::kPropertiesOffset)); 1091 __ movq(rbx, FieldOperand(rdx, JSObject::kPropertiesOffset));
1086 __ CompareRoot(FieldOperand(rbx, HeapObject::kMapOffset), 1092 __ CompareRoot(FieldOperand(rbx, HeapObject::kMapOffset),
1087 Heap::kHashTableMapRootIndex); 1093 Heap::kHashTableMapRootIndex);
1088 __ j(not_equal, &lookup_monomorphic_cache); 1094 __ j(not_equal, &lookup_monomorphic_cache);
1089 1095
1090 GenerateDictionaryLoad(masm, &slow_load, rbx, rcx, rax, rdi, rdi); 1096 GenerateDictionaryLoad(masm, &slow_load, rbx, rcx, rax, rdi, rdi);
1091 __ IncrementCounter(counters->keyed_call_generic_lookup_dict(), 1); 1097 __ IncrementCounter(counters->keyed_call_generic_lookup_dict(), 1);
1092 __ jmp(&do_call); 1098 __ jmp(&do_call);
1093 1099
1094 __ bind(&lookup_monomorphic_cache); 1100 __ bind(&lookup_monomorphic_cache);
1095 __ IncrementCounter(counters->keyed_call_generic_lookup_cache(), 1); 1101 __ IncrementCounter(counters->keyed_call_generic_lookup_cache(), 1);
1096 GenerateMonomorphicCacheProbe(masm, 1102 GenerateMonomorphicCacheProbe(masm,
1097 argc, 1103 argc,
1098 Code::KEYED_CALL_IC, 1104 Code::KEYED_CALL_IC,
1099 Code::kNoExtraICState); 1105 Code::kNoExtraICState);
1100 // Fall through on miss. 1106 // Fall through on miss.
1101 1107
1102 __ bind(&slow_call); 1108 __ bind(&slow_call);
1103 // This branch is taken if: 1109 // This branch is taken if:
1104 // - the receiver requires boxing or access check, 1110 // - the receiver requires boxing or access check,
1105 // - the key is neither smi nor internalized string, 1111 // - the key is neither smi nor a unique name,
1106 // - the value loaded is not a function, 1112 // - the value loaded is not a function,
1107 // - there is hope that the runtime will create a monomorphic call stub 1113 // - there is hope that the runtime will create a monomorphic call stub
1108 // that will get fetched next time. 1114 // that will get fetched next time.
1109 __ IncrementCounter(counters->keyed_call_generic_slow(), 1); 1115 __ IncrementCounter(counters->keyed_call_generic_slow(), 1);
1110 GenerateMiss(masm, argc); 1116 GenerateMiss(masm, argc);
1111 1117
1112 __ bind(&index_string); 1118 __ bind(&index_name);
1113 __ IndexFromHash(rbx, rcx); 1119 __ IndexFromHash(rbx, rcx);
1114 // Now jump to the place where smi keys are handled. 1120 // Now jump to the place where smi keys are handled.
1115 __ jmp(&index_smi); 1121 __ jmp(&index_smi);
1116 } 1122 }
1117 1123
1118 1124
1119 void KeyedCallIC::GenerateNormal(MacroAssembler* masm, int argc) { 1125 void KeyedCallIC::GenerateNormal(MacroAssembler* masm, int argc) {
1120 // ----------- S t a t e ------------- 1126 // ----------- S t a t e -------------
1121 // rcx : function name 1127 // rcx : function name
1122 // rsp[0] : return address 1128 // rsp[0] : return address
1123 // rsp[8] : argument argc 1129 // rsp[8] : argument argc
1124 // rsp[16] : argument argc - 1 1130 // rsp[16] : argument argc - 1
1125 // ... 1131 // ...
1126 // rsp[argc * 8] : argument 1 1132 // rsp[argc * 8] : argument 1
1127 // rsp[(argc + 1) * 8] : argument 0 = receiver 1133 // rsp[(argc + 1) * 8] : argument 0 = receiver
1128 // ----------------------------------- 1134 // -----------------------------------
1129 1135
1130 // Check if the name is a string. 1136 // Check if the name is really a name.
1131 Label miss; 1137 Label miss;
1132 __ JumpIfSmi(rcx, &miss); 1138 __ JumpIfSmi(rcx, &miss);
1133 Condition cond = masm->IsObjectStringType(rcx, rax, rax); 1139 Condition cond = masm->IsObjectNameType(rcx, rax, rax);
1134 __ j(NegateCondition(cond), &miss); 1140 __ j(NegateCondition(cond), &miss);
1135 CallICBase::GenerateNormal(masm, argc); 1141 CallICBase::GenerateNormal(masm, argc);
1136 __ bind(&miss); 1142 __ bind(&miss);
1137 GenerateMiss(masm, argc); 1143 GenerateMiss(masm, argc);
1138 } 1144 }
1139 1145
1140 1146
1141 static Operand GenerateMappedArgumentsLookup(MacroAssembler* masm, 1147 static Operand GenerateMappedArgumentsLookup(MacroAssembler* masm,
1142 Register object, 1148 Register object,
1143 Register key, 1149 Register key,
(...skipping 187 matching lines...) Expand 10 before | Expand all | Expand 10 after
1331 1337
1332 1338
1333 void LoadIC::GenerateNormal(MacroAssembler* masm) { 1339 void LoadIC::GenerateNormal(MacroAssembler* masm) {
1334 // ----------- S t a t e ------------- 1340 // ----------- S t a t e -------------
1335 // -- rax : receiver 1341 // -- rax : receiver
1336 // -- rcx : name 1342 // -- rcx : name
1337 // -- rsp[0] : return address 1343 // -- rsp[0] : return address
1338 // ----------------------------------- 1344 // -----------------------------------
1339 Label miss; 1345 Label miss;
1340 1346
1341 GenerateStringDictionaryReceiverCheck(masm, rax, rdx, rbx, &miss); 1347 GenerateNameDictionaryReceiverCheck(masm, rax, rdx, rbx, &miss);
1342 1348
1343 // rdx: elements 1349 // rdx: elements
1344 // Search the dictionary placing the result in rax. 1350 // Search the dictionary placing the result in rax.
1345 GenerateDictionaryLoad(masm, &miss, rdx, rcx, rbx, rdi, rax); 1351 GenerateDictionaryLoad(masm, &miss, rdx, rcx, rbx, rdi, rax);
1346 __ ret(0); 1352 __ ret(0);
1347 1353
1348 // Cache miss: Jump to runtime. 1354 // Cache miss: Jump to runtime.
1349 __ bind(&miss); 1355 __ bind(&miss);
1350 GenerateMiss(masm); 1356 GenerateMiss(masm);
1351 } 1357 }
(...skipping 106 matching lines...) Expand 10 before | Expand all | Expand 10 after
1458 void StoreIC::GenerateNormal(MacroAssembler* masm) { 1464 void StoreIC::GenerateNormal(MacroAssembler* masm) {
1459 // ----------- S t a t e ------------- 1465 // ----------- S t a t e -------------
1460 // -- rax : value 1466 // -- rax : value
1461 // -- rcx : name 1467 // -- rcx : name
1462 // -- rdx : receiver 1468 // -- rdx : receiver
1463 // -- rsp[0] : return address 1469 // -- rsp[0] : return address
1464 // ----------------------------------- 1470 // -----------------------------------
1465 1471
1466 Label miss; 1472 Label miss;
1467 1473
1468 GenerateStringDictionaryReceiverCheck(masm, rdx, rbx, rdi, &miss); 1474 GenerateNameDictionaryReceiverCheck(masm, rdx, rbx, rdi, &miss);
1469 1475
1470 GenerateDictionaryStore(masm, &miss, rbx, rcx, rax, r8, r9); 1476 GenerateDictionaryStore(masm, &miss, rbx, rcx, rax, r8, r9);
1471 Counters* counters = masm->isolate()->counters(); 1477 Counters* counters = masm->isolate()->counters();
1472 __ IncrementCounter(counters->store_normal_hit(), 1); 1478 __ IncrementCounter(counters->store_normal_hit(), 1);
1473 __ ret(0); 1479 __ ret(0);
1474 1480
1475 __ bind(&miss); 1481 __ bind(&miss);
1476 __ IncrementCounter(counters->store_normal_miss(), 1); 1482 __ IncrementCounter(counters->store_normal_miss(), 1);
1477 GenerateMiss(masm); 1483 GenerateMiss(masm);
1478 } 1484 }
(...skipping 201 matching lines...) Expand 10 before | Expand all | Expand 10 after
1680 Condition cc = (check == ENABLE_INLINED_SMI_CHECK) 1686 Condition cc = (check == ENABLE_INLINED_SMI_CHECK)
1681 ? (*jmp_address == Assembler::kJncShortOpcode ? not_zero : zero) 1687 ? (*jmp_address == Assembler::kJncShortOpcode ? not_zero : zero)
1682 : (*jmp_address == Assembler::kJnzShortOpcode ? not_carry : carry); 1688 : (*jmp_address == Assembler::kJnzShortOpcode ? not_carry : carry);
1683 *jmp_address = static_cast<byte>(Assembler::kJccShortPrefix | cc); 1689 *jmp_address = static_cast<byte>(Assembler::kJccShortPrefix | cc);
1684 } 1690 }
1685 1691
1686 1692
1687 } } // namespace v8::internal 1693 } } // namespace v8::internal
1688 1694
1689 #endif // V8_TARGET_ARCH_X64 1695 #endif // V8_TARGET_ARCH_X64
OLDNEW
« no previous file with comments | « src/x64/code-stubs-x64.cc ('k') | src/x64/macro-assembler-x64.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698