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

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

Issue 7348008: Merge up to 8597 to experimental/gc from the bleeding edge. (Closed) Base URL: http://v8.googlecode.com/svn/branches/experimental/gc/
Patch Set: '' Created 9 years, 5 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/full-codegen-x64.cc ('k') | src/x64/lithium-codegen-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 2011 the V8 project authors. All rights reserved. 1 // Copyright 2011 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 58 matching lines...) Expand 10 before | Expand all | Expand 10 after
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));
78 __ movb(r0, FieldOperand(r1, Map::kInstanceTypeOffset)); 78 __ movb(r0, FieldOperand(r1, Map::kInstanceTypeOffset));
79 __ cmpb(r0, Immediate(FIRST_JS_OBJECT_TYPE)); 79 __ cmpb(r0, Immediate(FIRST_SPEC_OBJECT_TYPE));
80 __ j(below, miss); 80 __ j(below, miss);
81 81
82 // If this assert fails, we have to check upper bound too. 82 // If this assert fails, we have to check upper bound too.
83 ASSERT(LAST_TYPE == JS_FUNCTION_TYPE); 83 STATIC_ASSERT(LAST_TYPE == LAST_SPEC_OBJECT_TYPE);
84 84
85 GenerateGlobalInstanceTypeCheck(masm, r0, miss); 85 GenerateGlobalInstanceTypeCheck(masm, r0, miss);
86 86
87 // Check for non-global object that requires access check. 87 // Check for non-global object that requires access check.
88 __ testb(FieldOperand(r1, Map::kBitFieldOffset), 88 __ testb(FieldOperand(r1, Map::kBitFieldOffset),
89 Immediate((1 << Map::kIsAccessCheckNeeded) | 89 Immediate((1 << Map::kIsAccessCheckNeeded) |
90 (1 << Map::kHasNamedInterceptor))); 90 (1 << Map::kHasNamedInterceptor)));
91 __ j(not_zero, miss); 91 __ j(not_zero, miss);
92 92
93 __ movq(r0, FieldOperand(receiver, JSObject::kPropertiesOffset)); 93 __ movq(r0, FieldOperand(receiver, JSObject::kPropertiesOffset));
(...skipping 124 matching lines...) Expand 10 before | Expand all | Expand 10 after
218 times_pointer_size, 218 times_pointer_size,
219 kValueOffset - kHeapObjectTag)); 219 kValueOffset - kHeapObjectTag));
220 __ movq(Operand(scratch1, 0), value); 220 __ movq(Operand(scratch1, 0), value);
221 221
222 // Update write barrier. Make sure not to clobber the value. 222 // Update write barrier. Make sure not to clobber the value.
223 __ movq(scratch0, value); 223 __ movq(scratch0, value);
224 __ RecordWrite(elements, scratch1, scratch0, kDontSaveFPRegs); 224 __ RecordWrite(elements, scratch1, scratch0, kDontSaveFPRegs);
225 } 225 }
226 226
227 227
228 static void GenerateNumberDictionaryLoad(MacroAssembler* masm,
229 Label* miss,
230 Register elements,
231 Register key,
232 Register r0,
233 Register r1,
234 Register r2,
235 Register result) {
236 // Register use:
237 //
238 // elements - holds the slow-case elements of the receiver on entry.
239 // Unchanged unless 'result' is the same register.
240 //
241 // key - holds the smi key on entry.
242 // Unchanged unless 'result' is the same register.
243 //
244 // Scratch registers:
245 //
246 // r0 - holds the untagged key on entry and holds the hash once computed.
247 //
248 // r1 - used to hold the capacity mask of the dictionary
249 //
250 // r2 - used for the index into the dictionary.
251 //
252 // result - holds the result on exit if the load succeeded.
253 // Allowed to be the same as 'key' or 'result'.
254 // Unchanged on bailout so 'key' or 'result' can be used
255 // in further computation.
256
257 Label done;
258
259 // Compute the hash code from the untagged key. This must be kept in sync
260 // with ComputeIntegerHash in utils.h.
261 //
262 // hash = ~hash + (hash << 15);
263 __ movl(r1, r0);
264 __ notl(r0);
265 __ shll(r1, Immediate(15));
266 __ addl(r0, r1);
267 // hash = hash ^ (hash >> 12);
268 __ movl(r1, r0);
269 __ shrl(r1, Immediate(12));
270 __ xorl(r0, r1);
271 // hash = hash + (hash << 2);
272 __ leal(r0, Operand(r0, r0, times_4, 0));
273 // hash = hash ^ (hash >> 4);
274 __ movl(r1, r0);
275 __ shrl(r1, Immediate(4));
276 __ xorl(r0, r1);
277 // hash = hash * 2057;
278 __ imull(r0, r0, Immediate(2057));
279 // hash = hash ^ (hash >> 16);
280 __ movl(r1, r0);
281 __ shrl(r1, Immediate(16));
282 __ xorl(r0, r1);
283
284 // Compute capacity mask.
285 __ SmiToInteger32(r1,
286 FieldOperand(elements, NumberDictionary::kCapacityOffset));
287 __ decl(r1);
288
289 // Generate an unrolled loop that performs a few probes before giving up.
290 const int kProbes = 4;
291 for (int i = 0; i < kProbes; i++) {
292 // Use r2 for index calculations and keep the hash intact in r0.
293 __ movq(r2, r0);
294 // Compute the masked index: (hash + i + i * i) & mask.
295 if (i > 0) {
296 __ addl(r2, Immediate(NumberDictionary::GetProbeOffset(i)));
297 }
298 __ and_(r2, r1);
299
300 // Scale the index by multiplying by the entry size.
301 ASSERT(NumberDictionary::kEntrySize == 3);
302 __ lea(r2, Operand(r2, r2, times_2, 0)); // r2 = r2 * 3
303
304 // Check if the key matches.
305 __ cmpq(key, FieldOperand(elements,
306 r2,
307 times_pointer_size,
308 NumberDictionary::kElementsStartOffset));
309 if (i != (kProbes - 1)) {
310 __ j(equal, &done);
311 } else {
312 __ j(not_equal, miss);
313 }
314 }
315
316 __ bind(&done);
317 // Check that the value is a normal propety.
318 const int kDetailsOffset =
319 NumberDictionary::kElementsStartOffset + 2 * kPointerSize;
320 ASSERT_EQ(NORMAL, 0);
321 __ Test(FieldOperand(elements, r2, times_pointer_size, kDetailsOffset),
322 Smi::FromInt(PropertyDetails::TypeField::mask()));
323 __ j(not_zero, miss);
324
325 // Get the value at the masked, scaled index.
326 const int kValueOffset =
327 NumberDictionary::kElementsStartOffset + kPointerSize;
328 __ movq(result, FieldOperand(elements, r2, times_pointer_size, kValueOffset));
329 }
330
331
332 void LoadIC::GenerateArrayLength(MacroAssembler* masm) { 228 void LoadIC::GenerateArrayLength(MacroAssembler* masm) {
333 // ----------- S t a t e ------------- 229 // ----------- S t a t e -------------
334 // -- rax : receiver 230 // -- rax : receiver
335 // -- rcx : name 231 // -- rcx : name
336 // -- rsp[0] : return address 232 // -- rsp[0] : return address
337 // ----------------------------------- 233 // -----------------------------------
338 Label miss; 234 Label miss;
339 235
340 StubCompiler::GenerateLoadArrayLength(masm, rax, rdx, &miss); 236 StubCompiler::GenerateLoadArrayLength(masm, rax, rdx, &miss);
341 __ bind(&miss); 237 __ bind(&miss);
(...skipping 159 matching lines...) Expand 10 before | Expand all | Expand 10 after
501 397
502 // Check that the key is a smi. 398 // Check that the key is a smi.
503 __ JumpIfNotSmi(rax, &check_string); 399 __ JumpIfNotSmi(rax, &check_string);
504 __ bind(&index_smi); 400 __ bind(&index_smi);
505 // Now the key is known to be a smi. This place is also jumped to from below 401 // Now the key is known to be a smi. This place is also jumped to from below
506 // where a numeric string is converted to a smi. 402 // where a numeric string is converted to a smi.
507 403
508 GenerateKeyedLoadReceiverCheck( 404 GenerateKeyedLoadReceiverCheck(
509 masm, rdx, rcx, Map::kHasIndexedInterceptor, &slow); 405 masm, rdx, rcx, Map::kHasIndexedInterceptor, &slow);
510 406
511 // Check the "has fast elements" bit in the receiver's map which is 407 // Check the receiver's map to see if it has fast elements.
512 // now in rcx. 408 __ CheckFastElements(rcx, &check_number_dictionary);
513 __ testb(FieldOperand(rcx, Map::kBitField2Offset),
514 Immediate(1 << Map::kHasFastElements));
515 __ j(zero, &check_number_dictionary);
516 409
517 GenerateFastArrayLoad(masm, 410 GenerateFastArrayLoad(masm,
518 rdx, 411 rdx,
519 rax, 412 rax,
520 rcx, 413 rcx,
521 rbx, 414 rbx,
522 rax, 415 rax,
523 NULL, 416 NULL,
524 &slow); 417 &slow);
525 Counters* counters = masm->isolate()->counters(); 418 Counters* counters = masm->isolate()->counters();
526 __ IncrementCounter(counters->keyed_load_generic_smi(), 1); 419 __ IncrementCounter(counters->keyed_load_generic_smi(), 1);
527 __ ret(0); 420 __ ret(0);
528 421
529 __ bind(&check_number_dictionary); 422 __ bind(&check_number_dictionary);
530 __ SmiToInteger32(rbx, rax); 423 __ SmiToInteger32(rbx, rax);
531 __ movq(rcx, FieldOperand(rdx, JSObject::kElementsOffset)); 424 __ movq(rcx, FieldOperand(rdx, JSObject::kElementsOffset));
532 425
533 // Check whether the elements is a number dictionary. 426 // Check whether the elements is a number dictionary.
534 // rdx: receiver 427 // rdx: receiver
535 // rax: key 428 // rax: key
536 // rbx: key as untagged int32 429 // rbx: key as untagged int32
537 // rcx: elements 430 // rcx: elements
538 __ CompareRoot(FieldOperand(rcx, HeapObject::kMapOffset), 431 __ CompareRoot(FieldOperand(rcx, HeapObject::kMapOffset),
539 Heap::kHashTableMapRootIndex); 432 Heap::kHashTableMapRootIndex);
540 __ j(not_equal, &slow); 433 __ j(not_equal, &slow);
541 GenerateNumberDictionaryLoad(masm, &slow, rcx, rax, rbx, r9, rdi, rax); 434 __ LoadFromNumberDictionary(&slow, rcx, rax, rbx, r9, rdi, rax);
542 __ ret(0); 435 __ ret(0);
543 436
544 __ bind(&slow); 437 __ bind(&slow);
545 // Slow case: Jump to runtime. 438 // Slow case: Jump to runtime.
546 // rdx: receiver 439 // rdx: receiver
547 // rax: key 440 // rax: key
548 __ IncrementCounter(counters->keyed_load_generic_slow(), 1); 441 __ IncrementCounter(counters->keyed_load_generic_slow(), 1);
549 GenerateRuntimeGetProperty(masm); 442 GenerateRuntimeGetProperty(masm);
550 443
551 __ bind(&check_string); 444 __ bind(&check_string);
(...skipping 171 matching lines...) Expand 10 before | Expand all | Expand 10 after
723 // to do this because this generic stub does not perform map checks. 616 // to do this because this generic stub does not perform map checks.
724 __ testb(FieldOperand(rbx, Map::kBitFieldOffset), 617 __ testb(FieldOperand(rbx, Map::kBitFieldOffset),
725 Immediate(1 << Map::kIsAccessCheckNeeded)); 618 Immediate(1 << Map::kIsAccessCheckNeeded));
726 __ j(not_zero, &slow_with_tagged_index); 619 __ j(not_zero, &slow_with_tagged_index);
727 // Check that the key is a smi. 620 // Check that the key is a smi.
728 __ JumpIfNotSmi(rcx, &slow_with_tagged_index); 621 __ JumpIfNotSmi(rcx, &slow_with_tagged_index);
729 __ SmiToInteger32(rcx, rcx); 622 __ SmiToInteger32(rcx, rcx);
730 623
731 __ CmpInstanceType(rbx, JS_ARRAY_TYPE); 624 __ CmpInstanceType(rbx, JS_ARRAY_TYPE);
732 __ j(equal, &array); 625 __ j(equal, &array);
733 // Check that the object is some kind of JS object. 626 // Check that the object is some kind of JSObject.
734 __ CmpInstanceType(rbx, FIRST_JS_OBJECT_TYPE); 627 __ CmpInstanceType(rbx, FIRST_JS_RECEIVER_TYPE);
735 __ j(below, &slow); 628 __ j(below, &slow);
629 __ CmpInstanceType(rbx, JS_PROXY_TYPE);
630 __ j(equal, &slow);
631 __ CmpInstanceType(rbx, JS_FUNCTION_PROXY_TYPE);
632 __ j(equal, &slow);
736 633
737 // Object case: Check key against length in the elements array. 634 // Object case: Check key against length in the elements array.
738 // rax: value 635 // rax: value
739 // rdx: JSObject 636 // rdx: JSObject
740 // rcx: index 637 // rcx: index
741 __ movq(rbx, FieldOperand(rdx, JSObject::kElementsOffset)); 638 __ movq(rbx, FieldOperand(rdx, JSObject::kElementsOffset));
742 // Check that the object is in fast mode and writable. 639 // Check that the object is in fast mode and writable.
743 __ CompareRoot(FieldOperand(rbx, HeapObject::kMapOffset), 640 __ CompareRoot(FieldOperand(rbx, HeapObject::kMapOffset),
744 Heap::kFixedArrayMapRootIndex); 641 Heap::kFixedArrayMapRootIndex);
745 __ j(not_equal, &slow); 642 __ j(not_equal, &slow);
(...skipping 142 matching lines...) Expand 10 before | Expand all | Expand 10 after
888 // rsp[argc * 8] : argument 1 785 // rsp[argc * 8] : argument 1
889 // rsp[(argc + 1) * 8] : argument 0 = receiver 786 // rsp[(argc + 1) * 8] : argument 0 = receiver
890 // ----------------------------------- 787 // -----------------------------------
891 __ JumpIfSmi(rdi, miss); 788 __ JumpIfSmi(rdi, miss);
892 // Check that the value is a JavaScript function. 789 // Check that the value is a JavaScript function.
893 __ CmpObjectType(rdi, JS_FUNCTION_TYPE, rdx); 790 __ CmpObjectType(rdi, JS_FUNCTION_TYPE, rdx);
894 __ j(not_equal, miss); 791 __ j(not_equal, miss);
895 792
896 // Invoke the function. 793 // Invoke the function.
897 ParameterCount actual(argc); 794 ParameterCount actual(argc);
898 __ InvokeFunction(rdi, actual, JUMP_FUNCTION); 795 __ InvokeFunction(rdi, actual, JUMP_FUNCTION,
796 NullCallWrapper(), CALL_AS_METHOD);
899 } 797 }
900 798
901 799
902 // The generated code falls through if the call should be handled by runtime. 800 // The generated code falls through if the call should be handled by runtime.
903 static void GenerateCallNormal(MacroAssembler* masm, int argc) { 801 static void GenerateCallNormal(MacroAssembler* masm, int argc) {
904 // ----------- S t a t e ------------- 802 // ----------- S t a t e -------------
905 // rcx : function name 803 // rcx : function name
906 // rsp[0] : return address 804 // rsp[0] : return address
907 // rsp[8] : argument argc 805 // rsp[8] : argument argc
908 // rsp[16] : argument argc - 1 806 // rsp[16] : argument argc - 1
(...skipping 184 matching lines...) Expand 10 before | Expand all | Expand 10 after
1093 991
1094 __ bind(&check_number_dictionary); 992 __ bind(&check_number_dictionary);
1095 // rax: elements 993 // rax: elements
1096 // rcx: smi key 994 // rcx: smi key
1097 // Check whether the elements is a number dictionary. 995 // Check whether the elements is a number dictionary.
1098 __ CompareRoot(FieldOperand(rax, HeapObject::kMapOffset), 996 __ CompareRoot(FieldOperand(rax, HeapObject::kMapOffset),
1099 Heap::kHashTableMapRootIndex); 997 Heap::kHashTableMapRootIndex);
1100 __ j(not_equal, &slow_load); 998 __ j(not_equal, &slow_load);
1101 __ SmiToInteger32(rbx, rcx); 999 __ SmiToInteger32(rbx, rcx);
1102 // ebx: untagged index 1000 // ebx: untagged index
1103 GenerateNumberDictionaryLoad(masm, &slow_load, rax, rcx, rbx, r9, rdi, rdi); 1001 __ LoadFromNumberDictionary(&slow_load, rax, rcx, rbx, r9, rdi, rdi);
1104 __ IncrementCounter(counters->keyed_call_generic_smi_dict(), 1); 1002 __ IncrementCounter(counters->keyed_call_generic_smi_dict(), 1);
1105 __ jmp(&do_call); 1003 __ jmp(&do_call);
1106 1004
1107 __ bind(&slow_load); 1005 __ bind(&slow_load);
1108 // This branch is taken when calling KeyedCallIC_Miss is neither required 1006 // This branch is taken when calling KeyedCallIC_Miss is neither required
1109 // nor beneficial. 1007 // nor beneficial.
1110 __ IncrementCounter(counters->keyed_call_generic_slow_load(), 1); 1008 __ IncrementCounter(counters->keyed_call_generic_slow_load(), 1);
1111 __ EnterInternalFrame(); 1009 __ EnterInternalFrame();
1112 __ push(rcx); // save the key 1010 __ push(rcx); // save the key
1113 __ push(rdx); // pass the receiver 1011 __ push(rdx); // pass the receiver
(...skipping 78 matching lines...) Expand 10 before | Expand all | Expand 10 after
1192 // rsp[16] : argument argc - 1 1090 // rsp[16] : argument argc - 1
1193 // ... 1091 // ...
1194 // rsp[argc * 8] : argument 1 1092 // rsp[argc * 8] : argument 1
1195 // rsp[(argc + 1) * 8] : argument 0 = receiver 1093 // rsp[(argc + 1) * 8] : argument 0 = receiver
1196 // ----------------------------------- 1094 // -----------------------------------
1197 1095
1198 GenerateCallMiss(masm, argc, IC::kKeyedCallIC_Miss, Code::kNoExtraICState); 1096 GenerateCallMiss(masm, argc, IC::kKeyedCallIC_Miss, Code::kNoExtraICState);
1199 } 1097 }
1200 1098
1201 1099
1100 static Operand GenerateMappedArgumentsLookup(MacroAssembler* masm,
1101 Register object,
1102 Register key,
1103 Register scratch1,
1104 Register scratch2,
1105 Register scratch3,
1106 Label* unmapped_case,
1107 Label* slow_case) {
1108 Heap* heap = masm->isolate()->heap();
1109
1110 // Check that the receiver is a JSObject. Because of the elements
1111 // map check later, we do not need to check for interceptors or
1112 // whether it requires access checks.
1113 __ JumpIfSmi(object, slow_case);
1114 // Check that the object is some kind of JSObject.
1115 __ CmpObjectType(object, FIRST_JS_RECEIVER_TYPE, scratch1);
1116 __ j(below, slow_case);
1117
1118 // Check that the key is a positive smi.
1119 Condition check = masm->CheckNonNegativeSmi(key);
1120 __ j(NegateCondition(check), slow_case);
1121
1122 // Load the elements into scratch1 and check its map. If not, jump
1123 // to the unmapped lookup with the parameter map in scratch1.
1124 Handle<Map> arguments_map(heap->non_strict_arguments_elements_map());
1125 __ movq(scratch1, FieldOperand(object, JSObject::kElementsOffset));
1126 __ CheckMap(scratch1, arguments_map, slow_case, DONT_DO_SMI_CHECK);
1127
1128 // Check if element is in the range of mapped arguments.
1129 __ movq(scratch2, FieldOperand(scratch1, FixedArray::kLengthOffset));
1130 __ SmiSubConstant(scratch2, scratch2, Smi::FromInt(2));
1131 __ cmpq(key, scratch2);
1132 __ j(greater_equal, unmapped_case);
1133
1134 // Load element index and check whether it is the hole.
1135 const int kHeaderSize = FixedArray::kHeaderSize + 2 * kPointerSize;
1136 __ SmiToInteger64(scratch3, key);
1137 __ movq(scratch2, FieldOperand(scratch1,
1138 scratch3,
1139 times_pointer_size,
1140 kHeaderSize));
1141 __ CompareRoot(scratch2, Heap::kTheHoleValueRootIndex);
1142 __ j(equal, unmapped_case);
1143
1144 // Load value from context and return it. We can reuse scratch1 because
1145 // we do not jump to the unmapped lookup (which requires the parameter
1146 // map in scratch1).
1147 __ movq(scratch1, FieldOperand(scratch1, FixedArray::kHeaderSize));
1148 __ SmiToInteger64(scratch3, scratch2);
1149 return FieldOperand(scratch1,
1150 scratch3,
1151 times_pointer_size,
1152 Context::kHeaderSize);
1153 }
1154
1155
1156 static Operand GenerateUnmappedArgumentsLookup(MacroAssembler* masm,
1157 Register key,
1158 Register parameter_map,
1159 Register scratch,
1160 Label* slow_case) {
1161 // Element is in arguments backing store, which is referenced by the
1162 // second element of the parameter_map. The parameter_map register
1163 // must be loaded with the parameter map of the arguments object and is
1164 // overwritten.
1165 const int kBackingStoreOffset = FixedArray::kHeaderSize + kPointerSize;
1166 Register backing_store = parameter_map;
1167 __ movq(backing_store, FieldOperand(parameter_map, kBackingStoreOffset));
1168 Handle<Map> fixed_array_map(masm->isolate()->heap()->fixed_array_map());
1169 __ CheckMap(backing_store, fixed_array_map, slow_case, DONT_DO_SMI_CHECK);
1170 __ movq(scratch, FieldOperand(backing_store, FixedArray::kLengthOffset));
1171 __ cmpq(key, scratch);
1172 __ j(greater_equal, slow_case);
1173 __ SmiToInteger64(scratch, key);
1174 return FieldOperand(backing_store,
1175 scratch,
1176 times_pointer_size,
1177 FixedArray::kHeaderSize);
1178 }
1179
1180
1181 void KeyedLoadIC::GenerateNonStrictArguments(MacroAssembler* masm) {
1182 // ----------- S t a t e -------------
1183 // -- rax : key
1184 // -- rdx : receiver
1185 // -- rsp[0] : return address
1186 // -----------------------------------
1187 Label slow, notin;
1188 Operand mapped_location =
1189 GenerateMappedArgumentsLookup(
1190 masm, rdx, rax, rbx, rcx, rdi, &notin, &slow);
1191 __ movq(rax, mapped_location);
1192 __ Ret();
1193 __ bind(&notin);
1194 // The unmapped lookup expects that the parameter map is in rbx.
1195 Operand unmapped_location =
1196 GenerateUnmappedArgumentsLookup(masm, rax, rbx, rcx, &slow);
1197 __ CompareRoot(unmapped_location, Heap::kTheHoleValueRootIndex);
1198 __ j(equal, &slow);
1199 __ movq(rax, unmapped_location);
1200 __ Ret();
1201 __ bind(&slow);
1202 GenerateMiss(masm, false);
1203 }
1204
1205
1206 void KeyedStoreIC::GenerateNonStrictArguments(MacroAssembler* masm) {
1207 // ----------- S t a t e -------------
1208 // -- rax : value
1209 // -- rcx : key
1210 // -- rdx : receiver
1211 // -- rsp[0] : return address
1212 // -----------------------------------
1213 Label slow, notin;
1214 Operand mapped_location = GenerateMappedArgumentsLookup(
1215 masm, rdx, rcx, rbx, rdi, r8, &notin, &slow);
1216 __ movq(mapped_location, rax);
1217 __ lea(r9, mapped_location);
1218 __ movq(r8, rax);
1219 __ RecordWrite(rbx,
1220 r9,
1221 r8,
1222 kDontSaveFPRegs,
1223 EMIT_REMEMBERED_SET,
1224 INLINE_SMI_CHECK);
1225 __ Ret();
1226 __ bind(&notin);
1227 // The unmapped lookup expects that the parameter map is in rbx.
1228 Operand unmapped_location =
1229 GenerateUnmappedArgumentsLookup(masm, rcx, rbx, rdi, &slow);
1230 __ movq(unmapped_location, rax);
1231 __ lea(r9, unmapped_location);
1232 __ movq(r8, rax);
1233 __ RecordWrite(rbx,
1234 r9,
1235 r8,
1236 kDontSaveFPRegs,
1237 EMIT_REMEMBERED_SET,
1238 INLINE_SMI_CHECK);
1239 __ Ret();
1240 __ bind(&slow);
1241 GenerateMiss(masm, false);
1242 }
1243
1244
1245 void KeyedCallIC::GenerateNonStrictArguments(MacroAssembler* masm,
1246 int argc) {
1247 // ----------- S t a t e -------------
1248 // rcx : function name
1249 // rsp[0] : return address
1250 // rsp[8] : argument argc
1251 // rsp[16] : argument argc - 1
1252 // ...
1253 // rsp[argc * 8] : argument 1
1254 // rsp[(argc + 1) * 8] : argument 0 = receiver
1255 // -----------------------------------
1256 Label slow, notin;
1257 __ movq(rdx, Operand(rsp, (argc + 1) * kPointerSize));
1258 Operand mapped_location = GenerateMappedArgumentsLookup(
1259 masm, rdx, rcx, rbx, rax, r8, &notin, &slow);
1260 __ movq(rdi, mapped_location);
1261 GenerateFunctionTailCall(masm, argc, &slow);
1262 __ bind(&notin);
1263 // The unmapped lookup expects that the parameter map is in rbx.
1264 Operand unmapped_location =
1265 GenerateUnmappedArgumentsLookup(masm, rcx, rbx, rax, &slow);
1266 __ CompareRoot(unmapped_location, Heap::kTheHoleValueRootIndex);
1267 __ j(equal, &slow);
1268 __ movq(rdi, unmapped_location);
1269 GenerateFunctionTailCall(masm, argc, &slow);
1270 __ bind(&slow);
1271 GenerateMiss(masm, argc);
1272 }
1273
1274
1202 void LoadIC::GenerateMegamorphic(MacroAssembler* masm) { 1275 void LoadIC::GenerateMegamorphic(MacroAssembler* masm) {
1203 // ----------- S t a t e ------------- 1276 // ----------- S t a t e -------------
1204 // -- rax : receiver 1277 // -- rax : receiver
1205 // -- rcx : name 1278 // -- rcx : name
1206 // -- rsp[0] : return address 1279 // -- rsp[0] : return address
1207 // ----------------------------------- 1280 // -----------------------------------
1208 1281
1209 // Probe the stub cache. 1282 // Probe the stub cache.
1210 Code::Flags flags = Code::ComputeFlags(Code::LOAD_IC, 1283 Code::Flags flags = Code::ComputeFlags(Code::LOAD_IC,
1211 NOT_IN_LOOP, 1284 NOT_IN_LOOP,
(...skipping 390 matching lines...) Expand 10 before | Expand all | Expand 10 after
1602 Condition cc = *jmp_address == Assembler::kJncShortOpcode 1675 Condition cc = *jmp_address == Assembler::kJncShortOpcode
1603 ? not_zero 1676 ? not_zero
1604 : zero; 1677 : zero;
1605 *jmp_address = static_cast<byte>(Assembler::kJccShortPrefix | cc); 1678 *jmp_address = static_cast<byte>(Assembler::kJccShortPrefix | cc);
1606 } 1679 }
1607 1680
1608 1681
1609 } } // namespace v8::internal 1682 } } // namespace v8::internal
1610 1683
1611 #endif // V8_TARGET_ARCH_X64 1684 #endif // V8_TARGET_ARCH_X64
OLDNEW
« no previous file with comments | « src/x64/full-codegen-x64.cc ('k') | src/x64/lithium-codegen-x64.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698