| OLD | NEW | 
|     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  Loading... | 
|   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 |  | 
|   370   // rax: key |  | 
|   371   // rbx: key as untagged int32 |   368   // rbx: key as untagged int32 | 
|   372   // rcx: elements |   369   // rax: elements | 
|   373   __ CompareRoot(FieldOperand(rcx, HeapObject::kMapOffset), |   370   __ CompareRoot(FieldOperand(rax, HeapObject::kMapOffset), | 
|   374                  Heap::kHashTableMapRootIndex); |   371                  Heap::kHashTableMapRootIndex); | 
|   375   __ j(not_equal, &slow); |   372   __ j(not_equal, &slow); | 
|   376   __ LoadFromNumberDictionary(&slow, rcx, rax, rbx, r9, rdi, rax); |   373   __ LoadFromNumberDictionary(&slow, rax, key, rbx, r9, rdi, rax); | 
|   377   __ ret(0); |   374   __ ret(0); | 
|   378  |   375  | 
|   379   __ bind(&slow); |   376   __ bind(&slow); | 
|   380   // Slow case: Jump to runtime. |   377   // Slow case: Jump to runtime. | 
|   381   // rdx: receiver |  | 
|   382   // rax: key |  | 
|   383   __ IncrementCounter(counters->keyed_load_generic_slow(), 1); |   378   __ IncrementCounter(counters->keyed_load_generic_slow(), 1); | 
|   384   GenerateRuntimeGetProperty(masm); |   379   GenerateRuntimeGetProperty(masm); | 
|   385  |   380  | 
|   386   __ bind(&check_name); |   381   __ bind(&check_name); | 
|   387   GenerateKeyNameCheck(masm, rax, rcx, rbx, &index_name, &slow); |   382   GenerateKeyNameCheck(masm, key, rax, rbx, &index_name, &slow); | 
|   388  |   383  | 
|   389   GenerateKeyedLoadReceiverCheck( |   384   GenerateKeyedLoadReceiverCheck( | 
|   390       masm, rdx, rcx, Map::kHasNamedInterceptor, &slow); |   385       masm, receiver, rax, Map::kHasNamedInterceptor, &slow); | 
|   391  |   386  | 
|   392   // If the receiver is a fast-case object, check the keyed lookup |   387   // If the receiver is a fast-case object, check the keyed lookup | 
|   393   // cache. Otherwise probe the dictionary leaving result in rcx. |   388   // cache. Otherwise probe the dictionary leaving result in key. | 
|   394   __ movp(rbx, FieldOperand(rdx, JSObject::kPropertiesOffset)); |   389   __ movp(rbx, FieldOperand(receiver, JSObject::kPropertiesOffset)); | 
|   395   __ CompareRoot(FieldOperand(rbx, HeapObject::kMapOffset), |   390   __ CompareRoot(FieldOperand(rbx, HeapObject::kMapOffset), | 
|   396                  Heap::kHashTableMapRootIndex); |   391                  Heap::kHashTableMapRootIndex); | 
|   397   __ j(equal, &probe_dictionary); |   392   __ j(equal, &probe_dictionary); | 
|   398  |   393  | 
|   399   // Load the map of the receiver, compute the keyed lookup cache hash |   394   // 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. |   395   // based on 32 bits of the map pointer and the string hash. | 
|   401   __ movp(rbx, FieldOperand(rdx, HeapObject::kMapOffset)); |   396   __ movp(rbx, FieldOperand(receiver, HeapObject::kMapOffset)); | 
|   402   __ movl(rcx, rbx); |   397   __ movl(rax, rbx); | 
|   403   __ shrl(rcx, Immediate(KeyedLookupCache::kMapHashShift)); |   398   __ shrl(rax, Immediate(KeyedLookupCache::kMapHashShift)); | 
|   404   __ movl(rdi, FieldOperand(rax, String::kHashFieldOffset)); |   399   __ movl(rdi, FieldOperand(key, String::kHashFieldOffset)); | 
|   405   __ shrl(rdi, Immediate(String::kHashShift)); |   400   __ shrl(rdi, Immediate(String::kHashShift)); | 
|   406   __ xorp(rcx, rdi); |   401   __ xorp(rax, rdi); | 
|   407   int mask = (KeyedLookupCache::kCapacityMask & KeyedLookupCache::kHashMask); |   402   int mask = (KeyedLookupCache::kCapacityMask & KeyedLookupCache::kHashMask); | 
|   408   __ andp(rcx, Immediate(mask)); |   403   __ andp(rax, Immediate(mask)); | 
|   409  |   404  | 
|   410   // Load the key (consisting of map and internalized string) from the cache and |   405   // Load the key (consisting of map and internalized string) from the cache and | 
|   411   // check for match. |   406   // check for match. | 
|   412   Label load_in_object_property; |   407   Label load_in_object_property; | 
|   413   static const int kEntriesPerBucket = KeyedLookupCache::kEntriesPerBucket; |   408   static const int kEntriesPerBucket = KeyedLookupCache::kEntriesPerBucket; | 
|   414   Label hit_on_nth_entry[kEntriesPerBucket]; |   409   Label hit_on_nth_entry[kEntriesPerBucket]; | 
|   415   ExternalReference cache_keys |   410   ExternalReference cache_keys | 
|   416       = ExternalReference::keyed_lookup_cache_keys(masm->isolate()); |   411       = ExternalReference::keyed_lookup_cache_keys(masm->isolate()); | 
|   417  |   412  | 
|   418   for (int i = 0; i < kEntriesPerBucket - 1; i++) { |   413   for (int i = 0; i < kEntriesPerBucket - 1; i++) { | 
|   419     Label try_next_entry; |   414     Label try_next_entry; | 
|   420     __ movp(rdi, rcx); |   415     __ movp(rdi, rax); | 
|   421     __ shlp(rdi, Immediate(kPointerSizeLog2 + 1)); |   416     __ shlp(rdi, Immediate(kPointerSizeLog2 + 1)); | 
|   422     __ LoadAddress(kScratchRegister, cache_keys); |   417     __ LoadAddress(kScratchRegister, cache_keys); | 
|   423     int off = kPointerSize * i * 2; |   418     int off = kPointerSize * i * 2; | 
|   424     __ cmpp(rbx, Operand(kScratchRegister, rdi, times_1, off)); |   419     __ cmpp(rbx, Operand(kScratchRegister, rdi, times_1, off)); | 
|   425     __ j(not_equal, &try_next_entry); |   420     __ j(not_equal, &try_next_entry); | 
|   426     __ cmpp(rax, Operand(kScratchRegister, rdi, times_1, off + kPointerSize)); |   421     __ cmpp(key, Operand(kScratchRegister, rdi, times_1, off + kPointerSize)); | 
|   427     __ j(equal, &hit_on_nth_entry[i]); |   422     __ j(equal, &hit_on_nth_entry[i]); | 
|   428     __ bind(&try_next_entry); |   423     __ bind(&try_next_entry); | 
|   429   } |   424   } | 
|   430  |   425  | 
|   431   int off = kPointerSize * (kEntriesPerBucket - 1) * 2; |   426   int off = kPointerSize * (kEntriesPerBucket - 1) * 2; | 
|   432   __ cmpp(rbx, Operand(kScratchRegister, rdi, times_1, off)); |   427   __ cmpp(rbx, Operand(kScratchRegister, rdi, times_1, off)); | 
|   433   __ j(not_equal, &slow); |   428   __ j(not_equal, &slow); | 
|   434   __ cmpp(rax, Operand(kScratchRegister, rdi, times_1, off + kPointerSize)); |   429   __ cmpp(key, Operand(kScratchRegister, rdi, times_1, off + kPointerSize)); | 
|   435   __ j(not_equal, &slow); |   430   __ j(not_equal, &slow); | 
|   436  |   431  | 
|   437   // Get field offset, which is a 32-bit integer. |   432   // Get field offset, which is a 32-bit integer. | 
|   438   ExternalReference cache_field_offsets |   433   ExternalReference cache_field_offsets | 
|   439       = ExternalReference::keyed_lookup_cache_field_offsets(masm->isolate()); |   434       = ExternalReference::keyed_lookup_cache_field_offsets(masm->isolate()); | 
|   440  |   435  | 
|   441   // Hit on nth entry. |   436   // Hit on nth entry. | 
|   442   for (int i = kEntriesPerBucket - 1; i >= 0; i--) { |   437   for (int i = kEntriesPerBucket - 1; i >= 0; i--) { | 
|   443     __ bind(&hit_on_nth_entry[i]); |   438     __ bind(&hit_on_nth_entry[i]); | 
|   444     if (i != 0) { |   439     if (i != 0) { | 
|   445       __ addl(rcx, Immediate(i)); |   440       __ addl(rax, Immediate(i)); | 
|   446     } |   441     } | 
|   447     __ LoadAddress(kScratchRegister, cache_field_offsets); |   442     __ LoadAddress(kScratchRegister, cache_field_offsets); | 
|   448     __ movl(rdi, Operand(kScratchRegister, rcx, times_4, 0)); |   443     __ movl(rdi, Operand(kScratchRegister, rax, times_4, 0)); | 
|   449     __ movzxbp(rcx, FieldOperand(rbx, Map::kInObjectPropertiesOffset)); |   444     __ movzxbp(rax, FieldOperand(rbx, Map::kInObjectPropertiesOffset)); | 
|   450     __ subp(rdi, rcx); |   445     __ subp(rdi, rax); | 
|   451     __ j(above_equal, &property_array_property); |   446     __ j(above_equal, &property_array_property); | 
|   452     if (i != 0) { |   447     if (i != 0) { | 
|   453       __ jmp(&load_in_object_property); |   448       __ jmp(&load_in_object_property); | 
|   454     } |   449     } | 
|   455   } |   450   } | 
|   456  |   451  | 
|   457   // Load in-object property. |   452   // Load in-object property. | 
|   458   __ bind(&load_in_object_property); |   453   __ bind(&load_in_object_property); | 
|   459   __ movzxbp(rcx, FieldOperand(rbx, Map::kInstanceSizeOffset)); |   454   __ movzxbp(rax, FieldOperand(rbx, Map::kInstanceSizeOffset)); | 
|   460   __ addp(rcx, rdi); |   455   __ addp(rax, rdi); | 
|   461   __ movp(rax, FieldOperand(rdx, rcx, times_pointer_size, 0)); |   456   __ movp(rax, FieldOperand(receiver, rax, times_pointer_size, 0)); | 
|   462   __ IncrementCounter(counters->keyed_load_generic_lookup_cache(), 1); |   457   __ IncrementCounter(counters->keyed_load_generic_lookup_cache(), 1); | 
|   463   __ ret(0); |   458   __ ret(0); | 
|   464  |   459  | 
|   465   // Load property array property. |   460   // Load property array property. | 
|   466   __ bind(&property_array_property); |   461   __ bind(&property_array_property); | 
|   467   __ movp(rax, FieldOperand(rdx, JSObject::kPropertiesOffset)); |   462   __ movp(rax, FieldOperand(receiver, JSObject::kPropertiesOffset)); | 
|   468   __ movp(rax, FieldOperand(rax, rdi, times_pointer_size, |   463   __ movp(rax, FieldOperand(rax, rdi, times_pointer_size, | 
|   469                             FixedArray::kHeaderSize)); |   464                             FixedArray::kHeaderSize)); | 
|   470   __ IncrementCounter(counters->keyed_load_generic_lookup_cache(), 1); |   465   __ IncrementCounter(counters->keyed_load_generic_lookup_cache(), 1); | 
|   471   __ ret(0); |   466   __ ret(0); | 
|   472  |   467  | 
|   473   // Do a quick inline probe of the receiver's dictionary, if it |   468   // Do a quick inline probe of the receiver's dictionary, if it | 
|   474   // exists. |   469   // exists. | 
|   475   __ bind(&probe_dictionary); |   470   __ bind(&probe_dictionary); | 
|   476   // rdx: receiver |  | 
|   477   // rax: key |  | 
|   478   // rbx: elements |   471   // rbx: elements | 
|   479  |   472  | 
|   480   __ movp(rcx, FieldOperand(rdx, JSObject::kMapOffset)); |   473   __ movp(rax, FieldOperand(receiver, JSObject::kMapOffset)); | 
|   481   __ movb(rcx, FieldOperand(rcx, Map::kInstanceTypeOffset)); |   474   __ movb(rax, FieldOperand(rax, Map::kInstanceTypeOffset)); | 
|   482   GenerateGlobalInstanceTypeCheck(masm, rcx, &slow); |   475   GenerateGlobalInstanceTypeCheck(masm, rax, &slow); | 
|   483  |   476  | 
|   484   GenerateDictionaryLoad(masm, &slow, rbx, rax, rcx, rdi, rax); |   477   GenerateDictionaryLoad(masm, &slow, rbx, key, rax, rdi, rax); | 
|   485   __ IncrementCounter(counters->keyed_load_generic_symbol(), 1); |   478   __ IncrementCounter(counters->keyed_load_generic_symbol(), 1); | 
|   486   __ ret(0); |   479   __ ret(0); | 
|   487  |   480  | 
|   488   __ bind(&index_name); |   481   __ bind(&index_name); | 
|   489   __ IndexFromHash(rbx, rax); |   482   __ IndexFromHash(rbx, key); | 
|   490   __ jmp(&index_smi); |   483   __ jmp(&index_smi); | 
|   491 } |   484 } | 
|   492  |   485  | 
|   493  |   486  | 
|   494 void KeyedLoadIC::GenerateString(MacroAssembler* masm) { |   487 void KeyedLoadIC::GenerateString(MacroAssembler* masm) { | 
|   495   // Return address is on the stack. |   488   // Return address is on the stack. | 
|   496   Label miss; |   489   Label miss; | 
|   497  |   490  | 
|   498   Register receiver = ReceiverRegister(); |   491   Register receiver = ReceiverRegister(); | 
|   499   Register index = NameRegister(); |   492   Register index = NameRegister(); | 
|   500   Register scratch = rcx; |   493   Register scratch = rbx; | 
|   501   Register result = rax; |   494   Register result = rax; | 
|   502   ASSERT(!scratch.is(receiver) && !scratch.is(index)); |   495   ASSERT(!scratch.is(receiver) && !scratch.is(index)); | 
|   503  |   496  | 
|   504   StringCharAtGenerator char_at_generator(receiver, |   497   StringCharAtGenerator char_at_generator(receiver, | 
|   505                                           index, |   498                                           index, | 
|   506                                           scratch, |   499                                           scratch, | 
|   507                                           result, |   500                                           result, | 
|   508                                           &miss,  // When not a string. |   501                                           &miss,  // When not a string. | 
|   509                                           &miss,  // When not a number. |   502                                           &miss,  // When not a number. | 
|   510                                           &miss,  // When index out of range. |   503                                           &miss,  // When index out of range. | 
|   511                                           STRING_INDEX_IS_ARRAY_INDEX); |   504                                           STRING_INDEX_IS_ARRAY_INDEX); | 
|   512   char_at_generator.GenerateFast(masm); |   505   char_at_generator.GenerateFast(masm); | 
|   513   __ ret(0); |   506   __ ret(0); | 
|   514  |   507  | 
|   515   StubRuntimeCallHelper call_helper; |   508   StubRuntimeCallHelper call_helper; | 
|   516   char_at_generator.GenerateSlow(masm, call_helper); |   509   char_at_generator.GenerateSlow(masm, call_helper); | 
|   517  |   510  | 
|   518   __ bind(&miss); |   511   __ bind(&miss); | 
|   519   GenerateMiss(masm); |   512   GenerateMiss(masm); | 
|   520 } |   513 } | 
|   521  |   514  | 
|   522  |   515  | 
|   523 void KeyedLoadIC::GenerateIndexedInterceptor(MacroAssembler* masm) { |   516 void KeyedLoadIC::GenerateIndexedInterceptor(MacroAssembler* masm) { | 
|   524   // Return address is on the stack. |   517   // Return address is on the stack. | 
|   525   Label slow; |   518   Label slow; | 
|   526  |   519  | 
|   527   Register receiver = ReceiverRegister(); |   520   Register receiver = ReceiverRegister(); | 
|   528   Register key = NameRegister(); |   521   Register key = NameRegister(); | 
|   529   Register scratch = rcx; |   522   Register scratch = rax; | 
|   530   ASSERT(!scratch.is(receiver) && !scratch.is(key)); |   523   ASSERT(!scratch.is(receiver) && !scratch.is(key)); | 
|   531  |   524  | 
|   532   // Check that the receiver isn't a smi. |   525   // Check that the receiver isn't a smi. | 
|   533   __ JumpIfSmi(receiver, &slow); |   526   __ JumpIfSmi(receiver, &slow); | 
|   534  |   527  | 
|   535   // Check that the key is an array index, that is Uint32. |   528   // Check that the key is an array index, that is Uint32. | 
|   536   STATIC_ASSERT(kSmiValueSize <= 32); |   529   STATIC_ASSERT(kSmiValueSize <= 32); | 
|   537   __ JumpUnlessNonNegativeSmi(key, &slow); |   530   __ JumpUnlessNonNegativeSmi(key, &slow); | 
|   538  |   531  | 
|   539   // Get the map of the receiver. |   532   // Get the map of the receiver. | 
| (...skipping 340 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
|   880   __ j(greater_equal, slow_case); |   873   __ j(greater_equal, slow_case); | 
|   881   __ SmiToInteger64(scratch, key); |   874   __ SmiToInteger64(scratch, key); | 
|   882   return FieldOperand(backing_store, |   875   return FieldOperand(backing_store, | 
|   883                       scratch, |   876                       scratch, | 
|   884                       times_pointer_size, |   877                       times_pointer_size, | 
|   885                       FixedArray::kHeaderSize); |   878                       FixedArray::kHeaderSize); | 
|   886 } |   879 } | 
|   887  |   880  | 
|   888  |   881  | 
|   889 void KeyedLoadIC::GenerateSloppyArguments(MacroAssembler* masm) { |   882 void KeyedLoadIC::GenerateSloppyArguments(MacroAssembler* masm) { | 
|   890   // ----------- S t a t e ------------- |   883   // The return address is on the stack. | 
|   891   //  -- rax    : key |   884   Register receiver = ReceiverRegister(); | 
|   892   //  -- rdx    : receiver |   885   Register key = NameRegister(); | 
|   893   //  -- rsp[0] : return address |   886   ASSERT(receiver.is(rdx)); | 
|   894   // ----------------------------------- |   887   ASSERT(key.is(rcx)); | 
|   895   ASSERT(rdx.is(ReceiverRegister())); |   888  | 
|   896   ASSERT(rax.is(NameRegister())); |  | 
|   897   Label slow, notin; |   889   Label slow, notin; | 
|   898   Operand mapped_location = |   890   Operand mapped_location = | 
|   899       GenerateMappedArgumentsLookup( |   891       GenerateMappedArgumentsLookup( | 
|   900           masm, rdx, rax, rbx, rcx, rdi, ¬in, &slow); |   892           masm, receiver, key, rbx, rax, rdi, ¬in, &slow); | 
|   901   __ movp(rax, mapped_location); |   893   __ movp(rax, mapped_location); | 
|   902   __ Ret(); |   894   __ Ret(); | 
|   903   __ bind(¬in); |   895   __ bind(¬in); | 
|   904   // The unmapped lookup expects that the parameter map is in rbx. |   896   // The unmapped lookup expects that the parameter map is in rbx. | 
|   905   Operand unmapped_location = |   897   Operand unmapped_location = | 
|   906       GenerateUnmappedArgumentsLookup(masm, rax, rbx, rcx, &slow); |   898       GenerateUnmappedArgumentsLookup(masm, key, rbx, rax, &slow); | 
|   907   __ CompareRoot(unmapped_location, Heap::kTheHoleValueRootIndex); |   899   __ CompareRoot(unmapped_location, Heap::kTheHoleValueRootIndex); | 
|   908   __ j(equal, &slow); |   900   __ j(equal, &slow); | 
|   909   __ movp(rax, unmapped_location); |   901   __ movp(rax, unmapped_location); | 
|   910   __ Ret(); |   902   __ Ret(); | 
|   911   __ bind(&slow); |   903   __ bind(&slow); | 
|   912   GenerateMiss(masm); |   904   GenerateMiss(masm); | 
|   913 } |   905 } | 
|   914  |   906  | 
|   915  |   907  | 
|   916 void KeyedStoreIC::GenerateSloppyArguments(MacroAssembler* masm) { |   908 void KeyedStoreIC::GenerateSloppyArguments(MacroAssembler* masm) { | 
| (...skipping 29 matching lines...) Expand all  Loading... | 
|   946                  kDontSaveFPRegs, |   938                  kDontSaveFPRegs, | 
|   947                  EMIT_REMEMBERED_SET, |   939                  EMIT_REMEMBERED_SET, | 
|   948                  INLINE_SMI_CHECK); |   940                  INLINE_SMI_CHECK); | 
|   949   __ Ret(); |   941   __ Ret(); | 
|   950   __ bind(&slow); |   942   __ bind(&slow); | 
|   951   GenerateMiss(masm); |   943   GenerateMiss(masm); | 
|   952 } |   944 } | 
|   953  |   945  | 
|   954  |   946  | 
|   955 void LoadIC::GenerateMegamorphic(MacroAssembler* masm) { |   947 void LoadIC::GenerateMegamorphic(MacroAssembler* masm) { | 
|   956   // ----------- S t a t e ------------- |   948   // The return address is on the stack. | 
|   957   //  -- rax    : receiver |   949   Register receiver = ReceiverRegister(); | 
|   958   //  -- rcx    : name |   950   Register name = NameRegister(); | 
|   959   //  -- rsp[0] : return address |   951   ASSERT(receiver.is(rdx)); | 
|   960   // ----------------------------------- |   952   ASSERT(name.is(rcx)); | 
|   961   ASSERT(rax.is(ReceiverRegister())); |  | 
|   962   ASSERT(rcx.is(NameRegister())); |  | 
|   963  |   953  | 
|   964   // Probe the stub cache. |   954   // Probe the stub cache. | 
|   965   Code::Flags flags = Code::ComputeHandlerFlags(Code::LOAD_IC); |   955   Code::Flags flags = Code::ComputeHandlerFlags(Code::LOAD_IC); | 
|   966   masm->isolate()->stub_cache()->GenerateProbe( |   956   masm->isolate()->stub_cache()->GenerateProbe( | 
|   967       masm, flags, rax, rcx, rbx, rdx); |   957       masm, flags, receiver, name, rbx, rax); | 
|   968  |   958  | 
|   969   GenerateMiss(masm); |   959   GenerateMiss(masm); | 
|   970 } |   960 } | 
|   971  |   961  | 
|   972  |   962  | 
|   973 void LoadIC::GenerateNormal(MacroAssembler* masm) { |   963 void LoadIC::GenerateNormal(MacroAssembler* masm) { | 
|   974   // ----------- S t a t e ------------- |   964   // ----------- S t a t e ------------- | 
|   975   //  -- rax    : receiver |   965   //  -- rdx    : receiver | 
|   976   //  -- rcx    : name |   966   //  -- rcx    : name | 
|   977   //  -- rsp[0] : return address |   967   //  -- rsp[0] : return address | 
|   978   // ----------------------------------- |   968   // ----------------------------------- | 
|   979   ASSERT(rax.is(ReceiverRegister())); |   969   ASSERT(rdx.is(ReceiverRegister())); | 
|   980   ASSERT(rcx.is(NameRegister())); |   970   ASSERT(rcx.is(NameRegister())); | 
|   981   Label miss, slow; |   971   Label miss, slow; | 
|   982  |   972  | 
|   983   GenerateNameDictionaryReceiverCheck(masm, rax, rdx, rbx, &miss); |   973   GenerateNameDictionaryReceiverCheck(masm, rdx, rax, rbx, &miss); | 
|   984  |   974  | 
|   985   //  rdx: elements |   975   //  rax: elements | 
|   986   // Search the dictionary placing the result in rax. |   976   // Search the dictionary placing the result in rax. | 
|   987   GenerateDictionaryLoad(masm, &slow, rdx, rcx, rbx, rdi, rax); |   977   GenerateDictionaryLoad(masm, &slow, rax, rcx, rbx, rdi, rax); | 
|   988   __ ret(0); |   978   __ ret(0); | 
|   989  |   979  | 
|   990   // Dictionary load failed, go slow (but don't miss). |   980   // Dictionary load failed, go slow (but don't miss). | 
|   991   __ bind(&slow); |   981   __ bind(&slow); | 
|   992   GenerateRuntimeGetProperty(masm); |   982   GenerateRuntimeGetProperty(masm); | 
|   993  |   983  | 
|   994   // Cache miss: Jump to runtime. |   984   // Cache miss: Jump to runtime. | 
|   995   __ bind(&miss); |   985   __ bind(&miss); | 
|   996   GenerateMiss(masm); |   986   GenerateMiss(masm); | 
|   997 } |   987 } | 
| (...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
|  1048   __ PushReturnAddressFrom(KeyedLoadIC_TempRegister()); |  1038   __ PushReturnAddressFrom(KeyedLoadIC_TempRegister()); | 
|  1049  |  1039  | 
|  1050   // Perform tail call to the entry. |  1040   // Perform tail call to the entry. | 
|  1051   ExternalReference ref = |  1041   ExternalReference ref = | 
|  1052       ExternalReference(IC_Utility(kKeyedLoadIC_Miss), masm->isolate()); |  1042       ExternalReference(IC_Utility(kKeyedLoadIC_Miss), masm->isolate()); | 
|  1053   __ TailCallExternalReference(ref, 2, 1); |  1043   __ TailCallExternalReference(ref, 2, 1); | 
|  1054 } |  1044 } | 
|  1055  |  1045  | 
|  1056  |  1046  | 
|  1057 // IC register specifications |  1047 // IC register specifications | 
|  1058 const Register LoadIC::ReceiverRegister() { return rax; } |  1048 const Register LoadIC::ReceiverRegister() { return rdx; } | 
|  1059 const Register LoadIC::NameRegister() { return rcx; } |  1049 const Register LoadIC::NameRegister() { return rcx; } | 
|  1060 const Register KeyedLoadIC::ReceiverRegister() { return rdx; } |  | 
|  1061 const Register KeyedLoadIC::NameRegister() { return rax; } |  | 
|  1062  |  1050  | 
|  1063  |  1051  | 
|  1064 void KeyedLoadIC::GenerateRuntimeGetProperty(MacroAssembler* masm) { |  1052 void KeyedLoadIC::GenerateRuntimeGetProperty(MacroAssembler* masm) { | 
|  1065   // The return address is on the stack. |  1053   // The return address is on the stack. | 
|  1066  |  1054  | 
|  1067   __ PopReturnAddressTo(KeyedLoadIC_TempRegister()); |  1055   __ PopReturnAddressTo(KeyedLoadIC_TempRegister()); | 
|  1068   __ Push(ReceiverRegister());  // receiver |  1056   __ Push(ReceiverRegister());  // receiver | 
|  1069   __ Push(NameRegister());  // name |  1057   __ Push(NameRegister());  // name | 
|  1070   __ PushReturnAddressFrom(KeyedLoadIC_TempRegister()); |  1058   __ PushReturnAddressFrom(KeyedLoadIC_TempRegister()); | 
|  1071  |  1059  | 
| (...skipping 235 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
|  1307   Condition cc = (check == ENABLE_INLINED_SMI_CHECK) |  1295   Condition cc = (check == ENABLE_INLINED_SMI_CHECK) | 
|  1308       ? (*jmp_address == Assembler::kJncShortOpcode ? not_zero : zero) |  1296       ? (*jmp_address == Assembler::kJncShortOpcode ? not_zero : zero) | 
|  1309       : (*jmp_address == Assembler::kJnzShortOpcode ? not_carry : carry); |  1297       : (*jmp_address == Assembler::kJnzShortOpcode ? not_carry : carry); | 
|  1310   *jmp_address = static_cast<byte>(Assembler::kJccShortPrefix | cc); |  1298   *jmp_address = static_cast<byte>(Assembler::kJccShortPrefix | cc); | 
|  1311 } |  1299 } | 
|  1312  |  1300  | 
|  1313  |  1301  | 
|  1314 } }  // namespace v8::internal |  1302 } }  // namespace v8::internal | 
|  1315  |  1303  | 
|  1316 #endif  // V8_TARGET_ARCH_X64 |  1304 #endif  // V8_TARGET_ARCH_X64 | 
| OLD | NEW |