| Index: src/x64/ic-x64.cc
|
| diff --git a/src/x64/ic-x64.cc b/src/x64/ic-x64.cc
|
| index a03eba17f8663652d2825c046445f55daea4be71..a96ddb0cfbaf6545fbaa20a8eba1ea745a9fc7d0 100644
|
| --- a/src/x64/ic-x64.cc
|
| +++ b/src/x64/ic-x64.cc
|
| @@ -327,32 +327,31 @@ static void GenerateKeyNameCheck(MacroAssembler* masm,
|
|
|
|
|
| void KeyedLoadIC::GenerateGeneric(MacroAssembler* masm) {
|
| - // ----------- S t a t e -------------
|
| - // -- rax : key
|
| - // -- rdx : receiver
|
| - // -- rsp[0] : return address
|
| - // -----------------------------------
|
| - ASSERT(rdx.is(ReceiverRegister()));
|
| - ASSERT(rax.is(NameRegister()));
|
| + // The return address is on the stack.
|
| Label slow, check_name, index_smi, index_name, property_array_property;
|
| Label probe_dictionary, check_number_dictionary;
|
|
|
| + Register receiver = ReceiverRegister();
|
| + Register key = NameRegister();
|
| + ASSERT(receiver.is(rdx));
|
| + ASSERT(key.is(rcx));
|
| +
|
| // Check that the key is a smi.
|
| - __ JumpIfNotSmi(rax, &check_name);
|
| + __ JumpIfNotSmi(key, &check_name);
|
| __ bind(&index_smi);
|
| // Now the key is known to be a smi. This place is also jumped to from below
|
| // where a numeric string is converted to a smi.
|
|
|
| GenerateKeyedLoadReceiverCheck(
|
| - masm, rdx, rcx, Map::kHasIndexedInterceptor, &slow);
|
| + masm, receiver, rax, Map::kHasIndexedInterceptor, &slow);
|
|
|
| // Check the receiver's map to see if it has fast elements.
|
| - __ CheckFastElements(rcx, &check_number_dictionary);
|
| + __ CheckFastElements(rax, &check_number_dictionary);
|
|
|
| GenerateFastArrayLoad(masm,
|
| - rdx,
|
| + receiver,
|
| + key,
|
| rax,
|
| - rcx,
|
| rbx,
|
| rax,
|
| NULL,
|
| @@ -362,50 +361,46 @@ void KeyedLoadIC::GenerateGeneric(MacroAssembler* masm) {
|
| __ ret(0);
|
|
|
| __ bind(&check_number_dictionary);
|
| - __ SmiToInteger32(rbx, rax);
|
| - __ movp(rcx, FieldOperand(rdx, JSObject::kElementsOffset));
|
| + __ SmiToInteger32(rbx, key);
|
| + __ movp(rax, FieldOperand(receiver, JSObject::kElementsOffset));
|
|
|
| // Check whether the elements is a number dictionary.
|
| - // rdx: receiver
|
| - // rax: key
|
| // rbx: key as untagged int32
|
| - // rcx: elements
|
| - __ CompareRoot(FieldOperand(rcx, HeapObject::kMapOffset),
|
| + // rax: elements
|
| + __ CompareRoot(FieldOperand(rax, HeapObject::kMapOffset),
|
| Heap::kHashTableMapRootIndex);
|
| __ j(not_equal, &slow);
|
| - __ LoadFromNumberDictionary(&slow, rcx, rax, rbx, r9, rdi, rax);
|
| + __ LoadFromNumberDictionary(&slow, rax, key, rbx, r9, rdi, rax);
|
| __ ret(0);
|
|
|
| __ bind(&slow);
|
| // Slow case: Jump to runtime.
|
| - // rdx: receiver
|
| - // rax: key
|
| __ IncrementCounter(counters->keyed_load_generic_slow(), 1);
|
| GenerateRuntimeGetProperty(masm);
|
|
|
| __ bind(&check_name);
|
| - GenerateKeyNameCheck(masm, rax, rcx, rbx, &index_name, &slow);
|
| + GenerateKeyNameCheck(masm, key, rax, rbx, &index_name, &slow);
|
|
|
| GenerateKeyedLoadReceiverCheck(
|
| - masm, rdx, rcx, Map::kHasNamedInterceptor, &slow);
|
| + masm, receiver, rax, Map::kHasNamedInterceptor, &slow);
|
|
|
| // If the receiver is a fast-case object, check the keyed lookup
|
| - // cache. Otherwise probe the dictionary leaving result in rcx.
|
| - __ movp(rbx, FieldOperand(rdx, JSObject::kPropertiesOffset));
|
| + // cache. Otherwise probe the dictionary leaving result in key.
|
| + __ movp(rbx, FieldOperand(receiver, JSObject::kPropertiesOffset));
|
| __ CompareRoot(FieldOperand(rbx, HeapObject::kMapOffset),
|
| Heap::kHashTableMapRootIndex);
|
| __ j(equal, &probe_dictionary);
|
|
|
| // Load the map of the receiver, compute the keyed lookup cache hash
|
| // based on 32 bits of the map pointer and the string hash.
|
| - __ movp(rbx, FieldOperand(rdx, HeapObject::kMapOffset));
|
| - __ movl(rcx, rbx);
|
| - __ shrl(rcx, Immediate(KeyedLookupCache::kMapHashShift));
|
| - __ movl(rdi, FieldOperand(rax, String::kHashFieldOffset));
|
| + __ movp(rbx, FieldOperand(receiver, HeapObject::kMapOffset));
|
| + __ movl(rax, rbx);
|
| + __ shrl(rax, Immediate(KeyedLookupCache::kMapHashShift));
|
| + __ movl(rdi, FieldOperand(key, String::kHashFieldOffset));
|
| __ shrl(rdi, Immediate(String::kHashShift));
|
| - __ xorp(rcx, rdi);
|
| + __ xorp(rax, rdi);
|
| int mask = (KeyedLookupCache::kCapacityMask & KeyedLookupCache::kHashMask);
|
| - __ andp(rcx, Immediate(mask));
|
| + __ andp(rax, Immediate(mask));
|
|
|
| // Load the key (consisting of map and internalized string) from the cache and
|
| // check for match.
|
| @@ -417,13 +412,13 @@ void KeyedLoadIC::GenerateGeneric(MacroAssembler* masm) {
|
|
|
| for (int i = 0; i < kEntriesPerBucket - 1; i++) {
|
| Label try_next_entry;
|
| - __ movp(rdi, rcx);
|
| + __ movp(rdi, rax);
|
| __ shlp(rdi, Immediate(kPointerSizeLog2 + 1));
|
| __ LoadAddress(kScratchRegister, cache_keys);
|
| int off = kPointerSize * i * 2;
|
| __ cmpp(rbx, Operand(kScratchRegister, rdi, times_1, off));
|
| __ j(not_equal, &try_next_entry);
|
| - __ cmpp(rax, Operand(kScratchRegister, rdi, times_1, off + kPointerSize));
|
| + __ cmpp(key, Operand(kScratchRegister, rdi, times_1, off + kPointerSize));
|
| __ j(equal, &hit_on_nth_entry[i]);
|
| __ bind(&try_next_entry);
|
| }
|
| @@ -431,7 +426,7 @@ void KeyedLoadIC::GenerateGeneric(MacroAssembler* masm) {
|
| int off = kPointerSize * (kEntriesPerBucket - 1) * 2;
|
| __ cmpp(rbx, Operand(kScratchRegister, rdi, times_1, off));
|
| __ j(not_equal, &slow);
|
| - __ cmpp(rax, Operand(kScratchRegister, rdi, times_1, off + kPointerSize));
|
| + __ cmpp(key, Operand(kScratchRegister, rdi, times_1, off + kPointerSize));
|
| __ j(not_equal, &slow);
|
|
|
| // Get field offset, which is a 32-bit integer.
|
| @@ -442,12 +437,12 @@ void KeyedLoadIC::GenerateGeneric(MacroAssembler* masm) {
|
| for (int i = kEntriesPerBucket - 1; i >= 0; i--) {
|
| __ bind(&hit_on_nth_entry[i]);
|
| if (i != 0) {
|
| - __ addl(rcx, Immediate(i));
|
| + __ addl(rax, Immediate(i));
|
| }
|
| __ LoadAddress(kScratchRegister, cache_field_offsets);
|
| - __ movl(rdi, Operand(kScratchRegister, rcx, times_4, 0));
|
| - __ movzxbp(rcx, FieldOperand(rbx, Map::kInObjectPropertiesOffset));
|
| - __ subp(rdi, rcx);
|
| + __ movl(rdi, Operand(kScratchRegister, rax, times_4, 0));
|
| + __ movzxbp(rax, FieldOperand(rbx, Map::kInObjectPropertiesOffset));
|
| + __ subp(rdi, rax);
|
| __ j(above_equal, &property_array_property);
|
| if (i != 0) {
|
| __ jmp(&load_in_object_property);
|
| @@ -456,15 +451,15 @@ void KeyedLoadIC::GenerateGeneric(MacroAssembler* masm) {
|
|
|
| // Load in-object property.
|
| __ bind(&load_in_object_property);
|
| - __ movzxbp(rcx, FieldOperand(rbx, Map::kInstanceSizeOffset));
|
| - __ addp(rcx, rdi);
|
| - __ movp(rax, FieldOperand(rdx, rcx, times_pointer_size, 0));
|
| + __ movzxbp(rax, FieldOperand(rbx, Map::kInstanceSizeOffset));
|
| + __ addp(rax, rdi);
|
| + __ movp(rax, FieldOperand(receiver, rax, times_pointer_size, 0));
|
| __ IncrementCounter(counters->keyed_load_generic_lookup_cache(), 1);
|
| __ ret(0);
|
|
|
| // Load property array property.
|
| __ bind(&property_array_property);
|
| - __ movp(rax, FieldOperand(rdx, JSObject::kPropertiesOffset));
|
| + __ movp(rax, FieldOperand(receiver, JSObject::kPropertiesOffset));
|
| __ movp(rax, FieldOperand(rax, rdi, times_pointer_size,
|
| FixedArray::kHeaderSize));
|
| __ IncrementCounter(counters->keyed_load_generic_lookup_cache(), 1);
|
| @@ -473,20 +468,18 @@ void KeyedLoadIC::GenerateGeneric(MacroAssembler* masm) {
|
| // Do a quick inline probe of the receiver's dictionary, if it
|
| // exists.
|
| __ bind(&probe_dictionary);
|
| - // rdx: receiver
|
| - // rax: key
|
| // rbx: elements
|
|
|
| - __ movp(rcx, FieldOperand(rdx, JSObject::kMapOffset));
|
| - __ movb(rcx, FieldOperand(rcx, Map::kInstanceTypeOffset));
|
| - GenerateGlobalInstanceTypeCheck(masm, rcx, &slow);
|
| + __ movp(rax, FieldOperand(receiver, JSObject::kMapOffset));
|
| + __ movb(rax, FieldOperand(rax, Map::kInstanceTypeOffset));
|
| + GenerateGlobalInstanceTypeCheck(masm, rax, &slow);
|
|
|
| - GenerateDictionaryLoad(masm, &slow, rbx, rax, rcx, rdi, rax);
|
| + GenerateDictionaryLoad(masm, &slow, rbx, key, rax, rdi, rax);
|
| __ IncrementCounter(counters->keyed_load_generic_symbol(), 1);
|
| __ ret(0);
|
|
|
| __ bind(&index_name);
|
| - __ IndexFromHash(rbx, rax);
|
| + __ IndexFromHash(rbx, key);
|
| __ jmp(&index_smi);
|
| }
|
|
|
| @@ -497,7 +490,7 @@ void KeyedLoadIC::GenerateString(MacroAssembler* masm) {
|
|
|
| Register receiver = ReceiverRegister();
|
| Register index = NameRegister();
|
| - Register scratch = rcx;
|
| + Register scratch = rbx;
|
| Register result = rax;
|
| ASSERT(!scratch.is(receiver) && !scratch.is(index));
|
|
|
| @@ -526,7 +519,7 @@ void KeyedLoadIC::GenerateIndexedInterceptor(MacroAssembler* masm) {
|
|
|
| Register receiver = ReceiverRegister();
|
| Register key = NameRegister();
|
| - Register scratch = rcx;
|
| + Register scratch = rax;
|
| ASSERT(!scratch.is(receiver) && !scratch.is(key));
|
|
|
| // Check that the receiver isn't a smi.
|
| @@ -887,23 +880,22 @@ static Operand GenerateUnmappedArgumentsLookup(MacroAssembler* masm,
|
|
|
|
|
| void KeyedLoadIC::GenerateSloppyArguments(MacroAssembler* masm) {
|
| - // ----------- S t a t e -------------
|
| - // -- rax : key
|
| - // -- rdx : receiver
|
| - // -- rsp[0] : return address
|
| - // -----------------------------------
|
| - ASSERT(rdx.is(ReceiverRegister()));
|
| - ASSERT(rax.is(NameRegister()));
|
| + // The return address is on the stack.
|
| + Register receiver = ReceiverRegister();
|
| + Register key = NameRegister();
|
| + ASSERT(receiver.is(rdx));
|
| + ASSERT(key.is(rcx));
|
| +
|
| Label slow, notin;
|
| Operand mapped_location =
|
| GenerateMappedArgumentsLookup(
|
| - masm, rdx, rax, rbx, rcx, rdi, ¬in, &slow);
|
| + masm, receiver, key, rbx, rax, rdi, ¬in, &slow);
|
| __ movp(rax, mapped_location);
|
| __ Ret();
|
| __ bind(¬in);
|
| // The unmapped lookup expects that the parameter map is in rbx.
|
| Operand unmapped_location =
|
| - GenerateUnmappedArgumentsLookup(masm, rax, rbx, rcx, &slow);
|
| + GenerateUnmappedArgumentsLookup(masm, key, rbx, rax, &slow);
|
| __ CompareRoot(unmapped_location, Heap::kTheHoleValueRootIndex);
|
| __ j(equal, &slow);
|
| __ movp(rax, unmapped_location);
|
| @@ -953,18 +945,16 @@ void KeyedStoreIC::GenerateSloppyArguments(MacroAssembler* masm) {
|
|
|
|
|
| void LoadIC::GenerateMegamorphic(MacroAssembler* masm) {
|
| - // ----------- S t a t e -------------
|
| - // -- rax : receiver
|
| - // -- rcx : name
|
| - // -- rsp[0] : return address
|
| - // -----------------------------------
|
| - ASSERT(rax.is(ReceiverRegister()));
|
| - ASSERT(rcx.is(NameRegister()));
|
| + // The return address is on the stack.
|
| + Register receiver = ReceiverRegister();
|
| + Register name = NameRegister();
|
| + ASSERT(receiver.is(rdx));
|
| + ASSERT(name.is(rcx));
|
|
|
| // Probe the stub cache.
|
| Code::Flags flags = Code::ComputeHandlerFlags(Code::LOAD_IC);
|
| masm->isolate()->stub_cache()->GenerateProbe(
|
| - masm, flags, rax, rcx, rbx, rdx);
|
| + masm, flags, receiver, name, rbx, rax);
|
|
|
| GenerateMiss(masm);
|
| }
|
| @@ -972,19 +962,19 @@ void LoadIC::GenerateMegamorphic(MacroAssembler* masm) {
|
|
|
| void LoadIC::GenerateNormal(MacroAssembler* masm) {
|
| // ----------- S t a t e -------------
|
| - // -- rax : receiver
|
| + // -- rdx : receiver
|
| // -- rcx : name
|
| // -- rsp[0] : return address
|
| // -----------------------------------
|
| - ASSERT(rax.is(ReceiverRegister()));
|
| + ASSERT(rdx.is(ReceiverRegister()));
|
| ASSERT(rcx.is(NameRegister()));
|
| Label miss, slow;
|
|
|
| - GenerateNameDictionaryReceiverCheck(masm, rax, rdx, rbx, &miss);
|
| + GenerateNameDictionaryReceiverCheck(masm, rdx, rax, rbx, &miss);
|
|
|
| - // rdx: elements
|
| + // rax: elements
|
| // Search the dictionary placing the result in rax.
|
| - GenerateDictionaryLoad(masm, &slow, rdx, rcx, rbx, rdi, rax);
|
| + GenerateDictionaryLoad(masm, &slow, rax, rcx, rbx, rdi, rax);
|
| __ ret(0);
|
|
|
| // Dictionary load failed, go slow (but don't miss).
|
| @@ -1055,10 +1045,8 @@ void KeyedLoadIC::GenerateMiss(MacroAssembler* masm) {
|
|
|
|
|
| // IC register specifications
|
| -const Register LoadIC::ReceiverRegister() { return rax; }
|
| +const Register LoadIC::ReceiverRegister() { return rdx; }
|
| const Register LoadIC::NameRegister() { return rcx; }
|
| -const Register KeyedLoadIC::ReceiverRegister() { return rdx; }
|
| -const Register KeyedLoadIC::NameRegister() { return rax; }
|
|
|
|
|
| void KeyedLoadIC::GenerateRuntimeGetProperty(MacroAssembler* masm) {
|
|
|