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

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

Issue 338963003: KeyedLoadIC should have same register spec as LoadIC. (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: A bit more refactoring. Created 6 years, 6 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
OLDNEW
1 // Copyright 2012 the V8 project authors. All rights reserved. 1 // Copyright 2012 the V8 project authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "src/v8.h" 5 #include "src/v8.h"
6 6
7 #if V8_TARGET_ARCH_X64 7 #if V8_TARGET_ARCH_X64
8 8
9 #include "src/codegen.h" 9 #include "src/codegen.h"
10 #include "src/ic-inl.h" 10 #include "src/ic-inl.h"
(...skipping 309 matching lines...) Expand 10 before | Expand all | Expand 10 after
320 __ testb(FieldOperand(map, Map::kInstanceTypeOffset), 320 __ testb(FieldOperand(map, Map::kInstanceTypeOffset),
321 Immediate(kIsNotInternalizedMask)); 321 Immediate(kIsNotInternalizedMask));
322 __ j(not_zero, not_unique); 322 __ j(not_zero, not_unique);
323 323
324 __ bind(&unique); 324 __ bind(&unique);
325 } 325 }
326 326
327 327
328 328
329 void KeyedLoadIC::GenerateGeneric(MacroAssembler* masm) { 329 void KeyedLoadIC::GenerateGeneric(MacroAssembler* masm) {
330 // ----------- S t a t e ------------- 330 // The return address is on the stack.
331 // -- rax : key
332 // -- rdx : receiver
333 // -- rsp[0] : return address
334 // -----------------------------------
335 ASSERT(rdx.is(ReceiverRegister()));
336 ASSERT(rax.is(NameRegister()));
337 Label slow, check_name, index_smi, index_name, property_array_property; 331 Label slow, check_name, index_smi, index_name, property_array_property;
338 Label probe_dictionary, check_number_dictionary; 332 Label probe_dictionary, check_number_dictionary;
339 333
334 Register receiver = ReceiverRegister();
335 Register key = NameRegister();
336 ASSERT(receiver.is(rdx));
337 ASSERT(key.is(rcx));
338
340 // Check that the key is a smi. 339 // Check that the key is a smi.
341 __ JumpIfNotSmi(rax, &check_name); 340 __ JumpIfNotSmi(key, &check_name);
342 __ bind(&index_smi); 341 __ bind(&index_smi);
343 // Now the key is known to be a smi. This place is also jumped to from below 342 // Now the key is known to be a smi. This place is also jumped to from below
344 // where a numeric string is converted to a smi. 343 // where a numeric string is converted to a smi.
345 344
346 GenerateKeyedLoadReceiverCheck( 345 GenerateKeyedLoadReceiverCheck(
347 masm, rdx, rcx, Map::kHasIndexedInterceptor, &slow); 346 masm, receiver, rax, Map::kHasIndexedInterceptor, &slow);
348 347
349 // Check the receiver's map to see if it has fast elements. 348 // Check the receiver's map to see if it has fast elements.
350 __ CheckFastElements(rcx, &check_number_dictionary); 349 __ CheckFastElements(rax, &check_number_dictionary);
351 350
352 GenerateFastArrayLoad(masm, 351 GenerateFastArrayLoad(masm,
353 rdx, 352 receiver,
353 key,
354 rax, 354 rax,
355 rcx,
356 rbx, 355 rbx,
357 rax, 356 rax,
358 NULL, 357 NULL,
359 &slow); 358 &slow);
360 Counters* counters = masm->isolate()->counters(); 359 Counters* counters = masm->isolate()->counters();
361 __ IncrementCounter(counters->keyed_load_generic_smi(), 1); 360 __ IncrementCounter(counters->keyed_load_generic_smi(), 1);
362 __ ret(0); 361 __ ret(0);
363 362
364 __ bind(&check_number_dictionary); 363 __ bind(&check_number_dictionary);
365 __ SmiToInteger32(rbx, rax); 364 __ SmiToInteger32(rbx, key);
366 __ movp(rcx, FieldOperand(rdx, JSObject::kElementsOffset)); 365 __ movp(rax, FieldOperand(receiver, JSObject::kElementsOffset));
367 366
368 // Check whether the elements is a number dictionary. 367 // Check whether the elements is a number dictionary.
369 // rdx: receiver 368 // receiver: receiver
Jakob Kummerow 2014/06/26 16:17:10 Yay for high-entropy comments! :-P AFAICS, the |r
mvstanton 2014/06/30 13:19:09 Will do, thanks.
370 // rax: key 369 // key: key
371 // rbx: key as untagged int32 370 // rbx: key as untagged int32
372 // rcx: elements 371 // rax: elements
373 __ CompareRoot(FieldOperand(rcx, HeapObject::kMapOffset), 372 __ CompareRoot(FieldOperand(rax, HeapObject::kMapOffset),
374 Heap::kHashTableMapRootIndex); 373 Heap::kHashTableMapRootIndex);
375 __ j(not_equal, &slow); 374 __ j(not_equal, &slow);
376 __ LoadFromNumberDictionary(&slow, rcx, rax, rbx, r9, rdi, rax); 375 __ LoadFromNumberDictionary(&slow, rax, key, rbx, r9, rdi, rax);
377 __ ret(0); 376 __ ret(0);
378 377
379 __ bind(&slow); 378 __ bind(&slow);
380 // Slow case: Jump to runtime. 379 // Slow case: Jump to runtime.
381 // rdx: receiver 380 // receiver: receiver
382 // rax: key 381 // key: key
383 __ IncrementCounter(counters->keyed_load_generic_slow(), 1); 382 __ IncrementCounter(counters->keyed_load_generic_slow(), 1);
384 GenerateRuntimeGetProperty(masm); 383 GenerateRuntimeGetProperty(masm);
385 384
386 __ bind(&check_name); 385 __ bind(&check_name);
387 GenerateKeyNameCheck(masm, rax, rcx, rbx, &index_name, &slow); 386 GenerateKeyNameCheck(masm, key, rax, rbx, &index_name, &slow);
388 387
389 GenerateKeyedLoadReceiverCheck( 388 GenerateKeyedLoadReceiverCheck(
390 masm, rdx, rcx, Map::kHasNamedInterceptor, &slow); 389 masm, receiver, rax, Map::kHasNamedInterceptor, &slow);
391 390
392 // If the receiver is a fast-case object, check the keyed lookup 391 // If the receiver is a fast-case object, check the keyed lookup
393 // cache. Otherwise probe the dictionary leaving result in rcx. 392 // cache. Otherwise probe the dictionary leaving result in key.
394 __ movp(rbx, FieldOperand(rdx, JSObject::kPropertiesOffset)); 393 __ movp(rbx, FieldOperand(receiver, JSObject::kPropertiesOffset));
395 __ CompareRoot(FieldOperand(rbx, HeapObject::kMapOffset), 394 __ CompareRoot(FieldOperand(rbx, HeapObject::kMapOffset),
396 Heap::kHashTableMapRootIndex); 395 Heap::kHashTableMapRootIndex);
397 __ j(equal, &probe_dictionary); 396 __ j(equal, &probe_dictionary);
398 397
399 // Load the map of the receiver, compute the keyed lookup cache hash 398 // Load the map of the receiver, compute the keyed lookup cache hash
400 // based on 32 bits of the map pointer and the string hash. 399 // based on 32 bits of the map pointer and the string hash.
401 __ movp(rbx, FieldOperand(rdx, HeapObject::kMapOffset)); 400 __ movp(rbx, FieldOperand(receiver, HeapObject::kMapOffset));
402 __ movl(rcx, rbx); 401 __ movl(rax, rbx);
403 __ shrl(rcx, Immediate(KeyedLookupCache::kMapHashShift)); 402 __ shrl(rax, Immediate(KeyedLookupCache::kMapHashShift));
404 __ movl(rdi, FieldOperand(rax, String::kHashFieldOffset)); 403 __ movl(rdi, FieldOperand(key, String::kHashFieldOffset));
405 __ shrl(rdi, Immediate(String::kHashShift)); 404 __ shrl(rdi, Immediate(String::kHashShift));
406 __ xorp(rcx, rdi); 405 __ xorp(rax, rdi);
407 int mask = (KeyedLookupCache::kCapacityMask & KeyedLookupCache::kHashMask); 406 int mask = (KeyedLookupCache::kCapacityMask & KeyedLookupCache::kHashMask);
408 __ andp(rcx, Immediate(mask)); 407 __ andp(rax, Immediate(mask));
409 408
410 // Load the key (consisting of map and internalized string) from the cache and 409 // Load the key (consisting of map and internalized string) from the cache and
411 // check for match. 410 // check for match.
412 Label load_in_object_property; 411 Label load_in_object_property;
413 static const int kEntriesPerBucket = KeyedLookupCache::kEntriesPerBucket; 412 static const int kEntriesPerBucket = KeyedLookupCache::kEntriesPerBucket;
414 Label hit_on_nth_entry[kEntriesPerBucket]; 413 Label hit_on_nth_entry[kEntriesPerBucket];
415 ExternalReference cache_keys 414 ExternalReference cache_keys
416 = ExternalReference::keyed_lookup_cache_keys(masm->isolate()); 415 = ExternalReference::keyed_lookup_cache_keys(masm->isolate());
417 416
418 for (int i = 0; i < kEntriesPerBucket - 1; i++) { 417 for (int i = 0; i < kEntriesPerBucket - 1; i++) {
419 Label try_next_entry; 418 Label try_next_entry;
420 __ movp(rdi, rcx); 419 __ movp(rdi, rax);
421 __ shlp(rdi, Immediate(kPointerSizeLog2 + 1)); 420 __ shlp(rdi, Immediate(kPointerSizeLog2 + 1));
422 __ LoadAddress(kScratchRegister, cache_keys); 421 __ LoadAddress(kScratchRegister, cache_keys);
423 int off = kPointerSize * i * 2; 422 int off = kPointerSize * i * 2;
424 __ cmpp(rbx, Operand(kScratchRegister, rdi, times_1, off)); 423 __ cmpp(rbx, Operand(kScratchRegister, rdi, times_1, off));
425 __ j(not_equal, &try_next_entry); 424 __ j(not_equal, &try_next_entry);
426 __ cmpp(rax, Operand(kScratchRegister, rdi, times_1, off + kPointerSize)); 425 __ cmpp(key, Operand(kScratchRegister, rdi, times_1, off + kPointerSize));
427 __ j(equal, &hit_on_nth_entry[i]); 426 __ j(equal, &hit_on_nth_entry[i]);
428 __ bind(&try_next_entry); 427 __ bind(&try_next_entry);
429 } 428 }
430 429
431 int off = kPointerSize * (kEntriesPerBucket - 1) * 2; 430 int off = kPointerSize * (kEntriesPerBucket - 1) * 2;
432 __ cmpp(rbx, Operand(kScratchRegister, rdi, times_1, off)); 431 __ cmpp(rbx, Operand(kScratchRegister, rdi, times_1, off));
433 __ j(not_equal, &slow); 432 __ j(not_equal, &slow);
434 __ cmpp(rax, Operand(kScratchRegister, rdi, times_1, off + kPointerSize)); 433 __ cmpp(key, Operand(kScratchRegister, rdi, times_1, off + kPointerSize));
435 __ j(not_equal, &slow); 434 __ j(not_equal, &slow);
436 435
437 // Get field offset, which is a 32-bit integer. 436 // Get field offset, which is a 32-bit integer.
438 ExternalReference cache_field_offsets 437 ExternalReference cache_field_offsets
439 = ExternalReference::keyed_lookup_cache_field_offsets(masm->isolate()); 438 = ExternalReference::keyed_lookup_cache_field_offsets(masm->isolate());
440 439
441 // Hit on nth entry. 440 // Hit on nth entry.
442 for (int i = kEntriesPerBucket - 1; i >= 0; i--) { 441 for (int i = kEntriesPerBucket - 1; i >= 0; i--) {
443 __ bind(&hit_on_nth_entry[i]); 442 __ bind(&hit_on_nth_entry[i]);
444 if (i != 0) { 443 if (i != 0) {
445 __ addl(rcx, Immediate(i)); 444 __ addl(rax, Immediate(i));
446 } 445 }
447 __ LoadAddress(kScratchRegister, cache_field_offsets); 446 __ LoadAddress(kScratchRegister, cache_field_offsets);
448 __ movl(rdi, Operand(kScratchRegister, rcx, times_4, 0)); 447 __ movl(rdi, Operand(kScratchRegister, rax, times_4, 0));
449 __ movzxbp(rcx, FieldOperand(rbx, Map::kInObjectPropertiesOffset)); 448 __ movzxbp(rax, FieldOperand(rbx, Map::kInObjectPropertiesOffset));
450 __ subp(rdi, rcx); 449 __ subp(rdi, rax);
451 __ j(above_equal, &property_array_property); 450 __ j(above_equal, &property_array_property);
452 if (i != 0) { 451 if (i != 0) {
453 __ jmp(&load_in_object_property); 452 __ jmp(&load_in_object_property);
454 } 453 }
455 } 454 }
456 455
457 // Load in-object property. 456 // Load in-object property.
458 __ bind(&load_in_object_property); 457 __ bind(&load_in_object_property);
459 __ movzxbp(rcx, FieldOperand(rbx, Map::kInstanceSizeOffset)); 458 __ movzxbp(rax, FieldOperand(rbx, Map::kInstanceSizeOffset));
460 __ addp(rcx, rdi); 459 __ addp(rax, rdi);
461 __ movp(rax, FieldOperand(rdx, rcx, times_pointer_size, 0)); 460 __ movp(rax, FieldOperand(receiver, rax, times_pointer_size, 0));
462 __ IncrementCounter(counters->keyed_load_generic_lookup_cache(), 1); 461 __ IncrementCounter(counters->keyed_load_generic_lookup_cache(), 1);
463 __ ret(0); 462 __ ret(0);
464 463
465 // Load property array property. 464 // Load property array property.
466 __ bind(&property_array_property); 465 __ bind(&property_array_property);
467 __ movp(rax, FieldOperand(rdx, JSObject::kPropertiesOffset)); 466 __ movp(rax, FieldOperand(receiver, JSObject::kPropertiesOffset));
468 __ movp(rax, FieldOperand(rax, rdi, times_pointer_size, 467 __ movp(rax, FieldOperand(rax, rdi, times_pointer_size,
469 FixedArray::kHeaderSize)); 468 FixedArray::kHeaderSize));
470 __ IncrementCounter(counters->keyed_load_generic_lookup_cache(), 1); 469 __ IncrementCounter(counters->keyed_load_generic_lookup_cache(), 1);
471 __ ret(0); 470 __ ret(0);
472 471
473 // Do a quick inline probe of the receiver's dictionary, if it 472 // Do a quick inline probe of the receiver's dictionary, if it
474 // exists. 473 // exists.
475 __ bind(&probe_dictionary); 474 __ bind(&probe_dictionary);
476 // rdx: receiver 475 // receiver: receiver
477 // rax: key 476 // key: key
478 // rbx: elements 477 // rbx: elements
479 478
480 __ movp(rcx, FieldOperand(rdx, JSObject::kMapOffset)); 479 __ movp(rax, FieldOperand(receiver, JSObject::kMapOffset));
481 __ movb(rcx, FieldOperand(rcx, Map::kInstanceTypeOffset)); 480 __ movb(rax, FieldOperand(rax, Map::kInstanceTypeOffset));
482 GenerateGlobalInstanceTypeCheck(masm, rcx, &slow); 481 GenerateGlobalInstanceTypeCheck(masm, rax, &slow);
483 482
484 GenerateDictionaryLoad(masm, &slow, rbx, rax, rcx, rdi, rax); 483 GenerateDictionaryLoad(masm, &slow, rbx, key, rax, rdi, rax);
485 __ IncrementCounter(counters->keyed_load_generic_symbol(), 1); 484 __ IncrementCounter(counters->keyed_load_generic_symbol(), 1);
486 __ ret(0); 485 __ ret(0);
487 486
488 __ bind(&index_name); 487 __ bind(&index_name);
489 __ IndexFromHash(rbx, rax); 488 __ IndexFromHash(rbx, key);
490 __ jmp(&index_smi); 489 __ jmp(&index_smi);
491 } 490 }
492 491
493 492
494 void KeyedLoadIC::GenerateString(MacroAssembler* masm) { 493 void KeyedLoadIC::GenerateString(MacroAssembler* masm) {
495 // Return address is on the stack. 494 // Return address is on the stack.
496 Label miss; 495 Label miss;
497 496
498 Register receiver = ReceiverRegister(); 497 Register receiver = ReceiverRegister();
499 Register index = NameRegister(); 498 Register index = NameRegister();
500 Register scratch = rcx; 499 Register scratch = rbx;
501 Register result = rax; 500 Register result = rax;
502 ASSERT(!scratch.is(receiver) && !scratch.is(index)); 501 ASSERT(!scratch.is(receiver) && !scratch.is(index));
503 502
504 StringCharAtGenerator char_at_generator(receiver, 503 StringCharAtGenerator char_at_generator(receiver,
505 index, 504 index,
506 scratch, 505 scratch,
507 result, 506 result,
508 &miss, // When not a string. 507 &miss, // When not a string.
509 &miss, // When not a number. 508 &miss, // When not a number.
510 &miss, // When index out of range. 509 &miss, // When index out of range.
511 STRING_INDEX_IS_ARRAY_INDEX); 510 STRING_INDEX_IS_ARRAY_INDEX);
512 char_at_generator.GenerateFast(masm); 511 char_at_generator.GenerateFast(masm);
513 __ ret(0); 512 __ ret(0);
514 513
515 StubRuntimeCallHelper call_helper; 514 StubRuntimeCallHelper call_helper;
516 char_at_generator.GenerateSlow(masm, call_helper); 515 char_at_generator.GenerateSlow(masm, call_helper);
517 516
518 __ bind(&miss); 517 __ bind(&miss);
519 GenerateMiss(masm); 518 GenerateMiss(masm);
520 } 519 }
521 520
522 521
523 void KeyedLoadIC::GenerateIndexedInterceptor(MacroAssembler* masm) { 522 void KeyedLoadIC::GenerateIndexedInterceptor(MacroAssembler* masm) {
524 // Return address is on the stack. 523 // Return address is on the stack.
525 Label slow; 524 Label slow;
526 525
527 Register receiver = ReceiverRegister(); 526 Register receiver = ReceiverRegister();
528 Register key = NameRegister(); 527 Register key = NameRegister();
529 Register scratch = rcx; 528 Register scratch = rax;
530 ASSERT(!scratch.is(receiver) && !scratch.is(key)); 529 ASSERT(!scratch.is(receiver) && !scratch.is(key));
531 530
532 // Check that the receiver isn't a smi. 531 // Check that the receiver isn't a smi.
533 __ JumpIfSmi(receiver, &slow); 532 __ JumpIfSmi(receiver, &slow);
534 533
535 // Check that the key is an array index, that is Uint32. 534 // Check that the key is an array index, that is Uint32.
536 STATIC_ASSERT(kSmiValueSize <= 32); 535 STATIC_ASSERT(kSmiValueSize <= 32);
537 __ JumpUnlessNonNegativeSmi(key, &slow); 536 __ JumpUnlessNonNegativeSmi(key, &slow);
538 537
539 // Get the map of the receiver. 538 // Get the map of the receiver.
(...skipping 340 matching lines...) Expand 10 before | Expand all | Expand 10 after
880 __ j(greater_equal, slow_case); 879 __ j(greater_equal, slow_case);
881 __ SmiToInteger64(scratch, key); 880 __ SmiToInteger64(scratch, key);
882 return FieldOperand(backing_store, 881 return FieldOperand(backing_store,
883 scratch, 882 scratch,
884 times_pointer_size, 883 times_pointer_size,
885 FixedArray::kHeaderSize); 884 FixedArray::kHeaderSize);
886 } 885 }
887 886
888 887
889 void KeyedLoadIC::GenerateSloppyArguments(MacroAssembler* masm) { 888 void KeyedLoadIC::GenerateSloppyArguments(MacroAssembler* masm) {
890 // ----------- S t a t e ------------- 889 // The return address is on the stack.
891 // -- rax : key 890 Register receiver = ReceiverRegister();
892 // -- rdx : receiver 891 Register key = NameRegister();
893 // -- rsp[0] : return address 892 ASSERT(receiver.is(rdx));
894 // ----------------------------------- 893 ASSERT(key.is(rcx));
895 ASSERT(rdx.is(ReceiverRegister())); 894
896 ASSERT(rax.is(NameRegister()));
897 Label slow, notin; 895 Label slow, notin;
898 Operand mapped_location = 896 Operand mapped_location =
899 GenerateMappedArgumentsLookup( 897 GenerateMappedArgumentsLookup(
900 masm, rdx, rax, rbx, rcx, rdi, &notin, &slow); 898 masm, receiver, key, rbx, rax, rdi, &notin, &slow);
901 __ movp(rax, mapped_location); 899 __ movp(rax, mapped_location);
902 __ Ret(); 900 __ Ret();
903 __ bind(&notin); 901 __ bind(&notin);
904 // The unmapped lookup expects that the parameter map is in rbx. 902 // The unmapped lookup expects that the parameter map is in rbx.
905 Operand unmapped_location = 903 Operand unmapped_location =
906 GenerateUnmappedArgumentsLookup(masm, rax, rbx, rcx, &slow); 904 GenerateUnmappedArgumentsLookup(masm, key, rbx, rax, &slow);
907 __ CompareRoot(unmapped_location, Heap::kTheHoleValueRootIndex); 905 __ CompareRoot(unmapped_location, Heap::kTheHoleValueRootIndex);
908 __ j(equal, &slow); 906 __ j(equal, &slow);
909 __ movp(rax, unmapped_location); 907 __ movp(rax, unmapped_location);
910 __ Ret(); 908 __ Ret();
911 __ bind(&slow); 909 __ bind(&slow);
912 GenerateMiss(masm); 910 GenerateMiss(masm);
913 } 911 }
914 912
915 913
916 void KeyedStoreIC::GenerateSloppyArguments(MacroAssembler* masm) { 914 void KeyedStoreIC::GenerateSloppyArguments(MacroAssembler* masm) {
(...skipping 30 matching lines...) Expand all
947 EMIT_REMEMBERED_SET, 945 EMIT_REMEMBERED_SET,
948 INLINE_SMI_CHECK); 946 INLINE_SMI_CHECK);
949 __ Ret(); 947 __ Ret();
950 __ bind(&slow); 948 __ bind(&slow);
951 GenerateMiss(masm); 949 GenerateMiss(masm);
952 } 950 }
953 951
954 952
955 void LoadIC::GenerateMegamorphic(MacroAssembler* masm) { 953 void LoadIC::GenerateMegamorphic(MacroAssembler* masm) {
956 // ----------- S t a t e ------------- 954 // ----------- S t a t e -------------
957 // -- rax : receiver 955 // -- rdx : receiver
958 // -- rcx : name 956 // -- rcx : name
959 // -- rsp[0] : return address 957 // -- rsp[0] : return address
960 // ----------------------------------- 958 // -----------------------------------
961 ASSERT(rax.is(ReceiverRegister())); 959 ASSERT(rdx.is(ReceiverRegister()));
962 ASSERT(rcx.is(NameRegister())); 960 ASSERT(rcx.is(NameRegister()));
963 961
964 // Probe the stub cache. 962 // Probe the stub cache.
965 Code::Flags flags = Code::ComputeHandlerFlags(Code::LOAD_IC); 963 Code::Flags flags = Code::ComputeHandlerFlags(Code::LOAD_IC);
966 masm->isolate()->stub_cache()->GenerateProbe( 964 masm->isolate()->stub_cache()->GenerateProbe(
967 masm, flags, rax, rcx, rbx, rdx); 965 masm, flags, rdx, rcx, rbx, rax);
968 966
969 GenerateMiss(masm); 967 GenerateMiss(masm);
970 } 968 }
971 969
972 970
973 void LoadIC::GenerateNormal(MacroAssembler* masm) { 971 void LoadIC::GenerateNormal(MacroAssembler* masm) {
974 // ----------- S t a t e ------------- 972 // ----------- S t a t e -------------
975 // -- rax : receiver 973 // -- rdx : receiver
976 // -- rcx : name 974 // -- rcx : name
977 // -- rsp[0] : return address 975 // -- rsp[0] : return address
978 // ----------------------------------- 976 // -----------------------------------
979 ASSERT(rax.is(ReceiverRegister())); 977 ASSERT(rdx.is(ReceiverRegister()));
980 ASSERT(rcx.is(NameRegister())); 978 ASSERT(rcx.is(NameRegister()));
981 Label miss, slow; 979 Label miss, slow;
982 980
983 GenerateNameDictionaryReceiverCheck(masm, rax, rdx, rbx, &miss); 981 GenerateNameDictionaryReceiverCheck(masm, rdx, rax, rbx, &miss);
984 982
985 // rdx: elements 983 // rax: elements
986 // Search the dictionary placing the result in rax. 984 // Search the dictionary placing the result in rax.
987 GenerateDictionaryLoad(masm, &slow, rdx, rcx, rbx, rdi, rax); 985 GenerateDictionaryLoad(masm, &slow, rax, rcx, rbx, rdi, rax);
988 __ ret(0); 986 __ ret(0);
989 987
990 // Dictionary load failed, go slow (but don't miss). 988 // Dictionary load failed, go slow (but don't miss).
991 __ bind(&slow); 989 __ bind(&slow);
992 GenerateRuntimeGetProperty(masm); 990 GenerateRuntimeGetProperty(masm);
993 991
994 // Cache miss: Jump to runtime. 992 // Cache miss: Jump to runtime.
995 __ bind(&miss); 993 __ bind(&miss);
996 GenerateMiss(masm); 994 GenerateMiss(masm);
997 } 995 }
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after
1048 __ PushReturnAddressFrom(KeyedLoadIC_TempRegister()); 1046 __ PushReturnAddressFrom(KeyedLoadIC_TempRegister());
1049 1047
1050 // Perform tail call to the entry. 1048 // Perform tail call to the entry.
1051 ExternalReference ref = 1049 ExternalReference ref =
1052 ExternalReference(IC_Utility(kKeyedLoadIC_Miss), masm->isolate()); 1050 ExternalReference(IC_Utility(kKeyedLoadIC_Miss), masm->isolate());
1053 __ TailCallExternalReference(ref, 2, 1); 1051 __ TailCallExternalReference(ref, 2, 1);
1054 } 1052 }
1055 1053
1056 1054
1057 // IC register specifications 1055 // IC register specifications
1058 const Register LoadIC::ReceiverRegister() { return rax; } 1056 const Register LoadIC::ReceiverRegister() { return rdx; }
1059 const Register LoadIC::NameRegister() { return rcx; } 1057 const Register LoadIC::NameRegister() { return rcx; }
1060 const Register KeyedLoadIC::ReceiverRegister() { return rdx; }
1061 const Register KeyedLoadIC::NameRegister() { return rax; }
1062 1058
1063 1059
1064 void KeyedLoadIC::GenerateRuntimeGetProperty(MacroAssembler* masm) { 1060 void KeyedLoadIC::GenerateRuntimeGetProperty(MacroAssembler* masm) {
1065 // The return address is on the stack. 1061 // The return address is on the stack.
1066 1062
1067 __ PopReturnAddressTo(KeyedLoadIC_TempRegister()); 1063 __ PopReturnAddressTo(KeyedLoadIC_TempRegister());
1068 __ Push(ReceiverRegister()); // receiver 1064 __ Push(ReceiverRegister()); // receiver
1069 __ Push(NameRegister()); // name 1065 __ Push(NameRegister()); // name
1070 __ PushReturnAddressFrom(KeyedLoadIC_TempRegister()); 1066 __ PushReturnAddressFrom(KeyedLoadIC_TempRegister());
1071 1067
(...skipping 235 matching lines...) Expand 10 before | Expand all | Expand 10 after
1307 Condition cc = (check == ENABLE_INLINED_SMI_CHECK) 1303 Condition cc = (check == ENABLE_INLINED_SMI_CHECK)
1308 ? (*jmp_address == Assembler::kJncShortOpcode ? not_zero : zero) 1304 ? (*jmp_address == Assembler::kJncShortOpcode ? not_zero : zero)
1309 : (*jmp_address == Assembler::kJnzShortOpcode ? not_carry : carry); 1305 : (*jmp_address == Assembler::kJnzShortOpcode ? not_carry : carry);
1310 *jmp_address = static_cast<byte>(Assembler::kJccShortPrefix | cc); 1306 *jmp_address = static_cast<byte>(Assembler::kJccShortPrefix | cc);
1311 } 1307 }
1312 1308
1313 1309
1314 } } // namespace v8::internal 1310 } } // namespace v8::internal
1315 1311
1316 #endif // V8_TARGET_ARCH_X64 1312 #endif // V8_TARGET_ARCH_X64
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698