diff --git a/src/arm/code-stubs-arm.cc b/src/arm/code-stubs-arm.cc index fd52b27082..33a7d5fa01 100644 --- a/src/arm/code-stubs-arm.cc +++ b/src/arm/code-stubs-arm.cc @@ -2650,84 +2650,6 @@ void NameDictionaryLookupStub::GenerateNegativeLookup(MacroAssembler* masm, __ b(ne, miss); } - -// Probe the name dictionary in the |elements| register. Jump to the -// |done| label if a property with the given name is found. Jump to -// the |miss| label otherwise. -// If lookup was successful |scratch2| will be equal to elements + 4 * index. -void NameDictionaryLookupStub::GeneratePositiveLookup(MacroAssembler* masm, - Label* miss, - Label* done, - Register elements, - Register name, - Register scratch1, - Register scratch2) { - DCHECK(!elements.is(scratch1)); - DCHECK(!elements.is(scratch2)); - DCHECK(!name.is(scratch1)); - DCHECK(!name.is(scratch2)); - - __ AssertName(name); - - // Compute the capacity mask. - __ ldr(scratch1, FieldMemOperand(elements, kCapacityOffset)); - __ SmiUntag(scratch1); - __ sub(scratch1, scratch1, Operand(1)); - - // Generate an unrolled loop that performs a few probes before - // giving up. Measurements done on Gmail indicate that 2 probes - // cover ~93% of loads from dictionaries. - for (int i = 0; i < kInlinedProbes; i++) { - // Compute the masked index: (hash + i + i * i) & mask. - __ ldr(scratch2, FieldMemOperand(name, Name::kHashFieldOffset)); - if (i > 0) { - // Add the probe offset (i + i * i) left shifted to avoid right shifting - // the hash in a separate instruction. The value hash + i + i * i is right - // shifted in the following and instruction. - DCHECK(NameDictionary::GetProbeOffset(i) < - 1 << (32 - Name::kHashFieldOffset)); - __ add(scratch2, scratch2, Operand( - NameDictionary::GetProbeOffset(i) << Name::kHashShift)); - } - __ and_(scratch2, scratch1, Operand(scratch2, LSR, Name::kHashShift)); - - // Scale the index by multiplying by the entry size. - STATIC_ASSERT(NameDictionary::kEntrySize == 3); - // scratch2 = scratch2 * 3. - __ add(scratch2, scratch2, Operand(scratch2, LSL, 1)); - - // Check if the key is identical to the name. - __ add(scratch2, elements, Operand(scratch2, LSL, 2)); - __ ldr(ip, FieldMemOperand(scratch2, kElementsStartOffset)); - __ cmp(name, Operand(ip)); - __ b(eq, done); - } - - const int spill_mask = - (lr.bit() | r6.bit() | r5.bit() | r4.bit() | - r3.bit() | r2.bit() | r1.bit() | r0.bit()) & - ~(scratch1.bit() | scratch2.bit()); - - __ stm(db_w, sp, spill_mask); - if (name.is(r0)) { - DCHECK(!elements.is(r1)); - __ Move(r1, name); - __ Move(r0, elements); - } else { - __ Move(r0, elements); - __ Move(r1, name); - } - NameDictionaryLookupStub stub(masm->isolate(), POSITIVE_LOOKUP); - __ CallStub(&stub); - __ cmp(r0, Operand::Zero()); - __ mov(scratch2, Operand(r2)); - __ ldm(ia_w, sp, spill_mask); - - __ b(ne, done); - __ b(eq, miss); -} - - void NameDictionaryLookupStub::Generate(MacroAssembler* masm) { // This stub overrides SometimesSetsUpAFrame() to return false. That means // we cannot call anything that could cause a GC from this stub. diff --git a/src/arm/code-stubs-arm.h b/src/arm/code-stubs-arm.h index 6f1ad083c9..6ec86ab292 100644 --- a/src/arm/code-stubs-arm.h +++ b/src/arm/code-stubs-arm.h @@ -269,14 +269,6 @@ class NameDictionaryLookupStub: public PlatformCodeStub { Handle name, Register scratch0); - static void GeneratePositiveLookup(MacroAssembler* masm, - Label* miss, - Label* done, - Register elements, - Register name, - Register r0, - Register r1); - bool SometimesSetsUpAFrame() override { return false; } private: diff --git a/src/arm64/code-stubs-arm64.cc b/src/arm64/code-stubs-arm64.cc index f61df949b0..8c9e7dd6f2 100644 --- a/src/arm64/code-stubs-arm64.cc +++ b/src/arm64/code-stubs-arm64.cc @@ -3081,91 +3081,6 @@ void DirectCEntryStub::GenerateCall(MacroAssembler* masm, __ Blr(lr); } - -// Probe the name dictionary in the 'elements' register. -// Jump to the 'done' label if a property with the given name is found. -// Jump to the 'miss' label otherwise. -// -// If lookup was successful 'scratch2' will be equal to elements + 4 * index. -// 'elements' and 'name' registers are preserved on miss. -void NameDictionaryLookupStub::GeneratePositiveLookup( - MacroAssembler* masm, - Label* miss, - Label* done, - Register elements, - Register name, - Register scratch1, - Register scratch2) { - DCHECK(!AreAliased(elements, name, scratch1, scratch2)); - - // Assert that name contains a string. - __ AssertName(name); - - // Compute the capacity mask. - __ Ldrsw(scratch1, UntagSmiFieldMemOperand(elements, kCapacityOffset)); - __ Sub(scratch1, scratch1, 1); - - // Generate an unrolled loop that performs a few probes before giving up. - for (int i = 0; i < kInlinedProbes; i++) { - // Compute the masked index: (hash + i + i * i) & mask. - __ Ldr(scratch2, FieldMemOperand(name, Name::kHashFieldOffset)); - if (i > 0) { - // Add the probe offset (i + i * i) left shifted to avoid right shifting - // the hash in a separate instruction. The value hash + i + i * i is right - // shifted in the following and instruction. - DCHECK(NameDictionary::GetProbeOffset(i) < - 1 << (32 - Name::kHashFieldOffset)); - __ Add(scratch2, scratch2, Operand( - NameDictionary::GetProbeOffset(i) << Name::kHashShift)); - } - __ And(scratch2, scratch1, Operand(scratch2, LSR, Name::kHashShift)); - - // Scale the index by multiplying by the element size. - STATIC_ASSERT(NameDictionary::kEntrySize == 3); - __ Add(scratch2, scratch2, Operand(scratch2, LSL, 1)); - - // Check if the key is identical to the name. - UseScratchRegisterScope temps(masm); - Register scratch3 = temps.AcquireX(); - __ Add(scratch2, elements, Operand(scratch2, LSL, kPointerSizeLog2)); - __ Ldr(scratch3, FieldMemOperand(scratch2, kElementsStartOffset)); - __ Cmp(name, scratch3); - __ B(eq, done); - } - - // The inlined probes didn't find the entry. - // Call the complete stub to scan the whole dictionary. - - CPURegList spill_list(CPURegister::kRegister, kXRegSizeInBits, 0, 6); - spill_list.Combine(lr); - spill_list.Remove(scratch1); - spill_list.Remove(scratch2); - - __ PushCPURegList(spill_list); - - if (name.is(x0)) { - DCHECK(!elements.is(x1)); - __ Mov(x1, name); - __ Mov(x0, elements); - } else { - __ Mov(x0, elements); - __ Mov(x1, name); - } - - Label not_found; - NameDictionaryLookupStub stub(masm->isolate(), POSITIVE_LOOKUP); - __ CallStub(&stub); - __ Cbz(x0, ¬_found); - __ Mov(scratch2, x2); // Move entry index into scratch2. - __ PopCPURegList(spill_list); - __ B(done); - - __ Bind(¬_found); - __ PopCPURegList(spill_list); - __ B(miss); -} - - void NameDictionaryLookupStub::GenerateNegativeLookup(MacroAssembler* masm, Label* miss, Label* done, diff --git a/src/arm64/code-stubs-arm64.h b/src/arm64/code-stubs-arm64.h index 4b56b5468f..13e1b9d234 100644 --- a/src/arm64/code-stubs-arm64.h +++ b/src/arm64/code-stubs-arm64.h @@ -355,14 +355,6 @@ class NameDictionaryLookupStub: public PlatformCodeStub { Handle name, Register scratch0); - static void GeneratePositiveLookup(MacroAssembler* masm, - Label* miss, - Label* done, - Register elements, - Register name, - Register scratch1, - Register scratch2); - bool SometimesSetsUpAFrame() override { return false; } private: diff --git a/src/builtins/builtins-handler.cc b/src/builtins/builtins-handler.cc index d48e564255..42b35d0d2f 100644 --- a/src/builtins/builtins-handler.cc +++ b/src/builtins/builtins-handler.cc @@ -108,8 +108,34 @@ void Builtins::Generate_LoadIC_Miss(compiler::CodeAssemblerState* state) { slot, vector); } -void Builtins::Generate_LoadIC_Normal(MacroAssembler* masm) { - LoadIC::GenerateNormal(masm); +TF_BUILTIN(LoadIC_Normal, CodeStubAssembler) { + typedef LoadWithVectorDescriptor Descriptor; + + Node* receiver = Parameter(Descriptor::kReceiver); + Node* name = Parameter(Descriptor::kName); + Node* context = Parameter(Descriptor::kContext); + + Label slow(this); + { + Node* properties = LoadProperties(receiver); + Variable var_name_index(this, MachineType::PointerRepresentation()); + Label found(this, &var_name_index); + NameDictionaryLookup(properties, name, &found, + &var_name_index, &slow); + Bind(&found); + { + Variable var_details(this, MachineRepresentation::kWord32); + Variable var_value(this, MachineRepresentation::kTagged); + LoadPropertyFromNameDictionary(properties, var_name_index.value(), + &var_details, &var_value); + Node* value = CallGetterIfAccessor(var_value.value(), var_details.value(), + context, receiver, &slow); + Return(value); + } + } + + Bind(&slow); + TailCallRuntime(Runtime::kGetProperty, context, receiver, name); } void Builtins::Generate_LoadIC_Slow(compiler::CodeAssemblerState* state) { @@ -140,8 +166,47 @@ void Builtins::Generate_StoreIC_Miss(compiler::CodeAssemblerState* state) { vector, receiver, name); } -void Builtins::Generate_StoreIC_Normal(MacroAssembler* masm) { - StoreIC::GenerateNormal(masm); +TF_BUILTIN(StoreIC_Normal, CodeStubAssembler) { + typedef StoreWithVectorDescriptor Descriptor; + + Node* receiver = Parameter(Descriptor::kReceiver); + Node* name = Parameter(Descriptor::kName); + Node* value = Parameter(Descriptor::kValue); + Node* slot = Parameter(Descriptor::kSlot); + Node* vector = Parameter(Descriptor::kVector); + Node* context = Parameter(Descriptor::kContext); + + Label slow(this); + { + Node* properties = LoadProperties(receiver); + Variable var_name_index(this, MachineType::PointerRepresentation()); + Label found(this, &var_name_index); + NameDictionaryLookup(properties, name, &found, + &var_name_index, &slow); + Bind(&found); + { + const int kNameToDetailsOffset = (NameDictionary::kEntryDetailsIndex - + NameDictionary::kEntryKeyIndex) * + kPointerSize; + Node* details = LoadFixedArrayElement(properties, var_name_index.value(), + kNameToDetailsOffset); + // Check that the property is a writable data property (no accessor). + const int kTypeAndReadOnlyMask = PropertyDetails::KindField::kMask | + PropertyDetails::kAttributesReadOnlyMask; + STATIC_ASSERT(kData == 0); + GotoIf(IsSetSmi(details, kTypeAndReadOnlyMask), &slow); + const int kNameToValueOffset = + (NameDictionary::kEntryValueIndex - NameDictionary::kEntryKeyIndex) * + kPointerSize; + StoreFixedArrayElement(properties, var_name_index.value(), value, + UPDATE_WRITE_BARRIER, kNameToValueOffset); + Return(value); + } + } + + Bind(&slow); + TailCallRuntime(Runtime::kStoreIC_Miss, context, value, slot, vector, + receiver, name); } void Builtins::Generate_StoreIC_Setter_ForDeopt(MacroAssembler* masm) { diff --git a/src/builtins/builtins.h b/src/builtins/builtins.h index dcff15068f..6962dfd040 100644 --- a/src/builtins/builtins.h +++ b/src/builtins/builtins.h @@ -224,10 +224,10 @@ namespace internal { TFS(LoadGlobalIC_Slow, HANDLER, Code::LOAD_GLOBAL_IC, LoadGlobalWithVector) \ ASH(LoadIC_Getter_ForDeopt, LOAD_IC, kNoExtraICState) \ TFS(LoadIC_Miss, BUILTIN, kNoExtraICState, LoadWithVector) \ - ASH(LoadIC_Normal, HANDLER, Code::LOAD_IC) \ + TFS(LoadIC_Normal, HANDLER, Code::LOAD_IC, LoadWithVector) \ TFS(LoadIC_Slow, HANDLER, Code::LOAD_IC, LoadWithVector) \ TFS(StoreIC_Miss, BUILTIN, kNoExtraICState, StoreWithVector) \ - ASH(StoreIC_Normal, HANDLER, Code::STORE_IC) \ + TFS(StoreIC_Normal, HANDLER, Code::STORE_IC, StoreWithVector) \ ASH(StoreIC_Setter_ForDeopt, STORE_IC, StoreICState::kStrictModeState) \ TFS(StoreIC_SlowSloppy, HANDLER, Code::STORE_IC, StoreWithVector) \ TFS(StoreIC_SlowStrict, HANDLER, Code::STORE_IC, StoreWithVector) \ diff --git a/src/ia32/code-stubs-ia32.cc b/src/ia32/code-stubs-ia32.cc index a61db8f6df..42bfc4f790 100644 --- a/src/ia32/code-stubs-ia32.cc +++ b/src/ia32/code-stubs-ia32.cc @@ -2644,67 +2644,6 @@ void NameDictionaryLookupStub::GenerateNegativeLookup(MacroAssembler* masm, __ jmp(done); } - -// Probe the name dictionary in the |elements| register. Jump to the -// |done| label if a property with the given name is found leaving the -// index into the dictionary in |r0|. Jump to the |miss| label -// otherwise. -void NameDictionaryLookupStub::GeneratePositiveLookup(MacroAssembler* masm, - Label* miss, - Label* done, - Register elements, - Register name, - Register r0, - Register r1) { - DCHECK(!elements.is(r0)); - DCHECK(!elements.is(r1)); - DCHECK(!name.is(r0)); - DCHECK(!name.is(r1)); - - __ AssertName(name); - - __ mov(r1, FieldOperand(elements, kCapacityOffset)); - __ shr(r1, kSmiTagSize); // convert smi to int - __ dec(r1); - - // Generate an unrolled loop that performs a few probes before - // giving up. Measurements done on Gmail indicate that 2 probes - // cover ~93% of loads from dictionaries. - for (int i = 0; i < kInlinedProbes; i++) { - // Compute the masked index: (hash + i + i * i) & mask. - __ mov(r0, FieldOperand(name, Name::kHashFieldOffset)); - __ shr(r0, Name::kHashShift); - if (i > 0) { - __ add(r0, Immediate(NameDictionary::GetProbeOffset(i))); - } - __ and_(r0, r1); - - // Scale the index by multiplying by the entry size. - STATIC_ASSERT(NameDictionary::kEntrySize == 3); - __ lea(r0, Operand(r0, r0, times_2, 0)); // r0 = r0 * 3 - - // Check if the key is identical to the name. - __ cmp(name, Operand(elements, - r0, - times_4, - kElementsStartOffset - kHeapObjectTag)); - __ j(equal, done); - } - - NameDictionaryLookupStub stub(masm->isolate(), elements, r1, r0, - POSITIVE_LOOKUP); - __ push(name); - __ mov(r0, FieldOperand(name, Name::kHashFieldOffset)); - __ shr(r0, Name::kHashShift); - __ push(r0); - __ CallStub(&stub); - - __ test(r1, r1); - __ j(zero, miss); - __ jmp(done); -} - - void NameDictionaryLookupStub::Generate(MacroAssembler* masm) { // This stub overrides SometimesSetsUpAFrame() to return false. That means // we cannot call anything that could cause a GC from this stub. diff --git a/src/ia32/code-stubs-ia32.h b/src/ia32/code-stubs-ia32.h index a2dacd32d7..649e2ccf16 100644 --- a/src/ia32/code-stubs-ia32.h +++ b/src/ia32/code-stubs-ia32.h @@ -58,14 +58,6 @@ class NameDictionaryLookupStub: public PlatformCodeStub { Handle name, Register r0); - static void GeneratePositiveLookup(MacroAssembler* masm, - Label* miss, - Label* done, - Register elements, - Register name, - Register r0, - Register r1); - bool SometimesSetsUpAFrame() override { return false; } private: diff --git a/src/ic/arm/ic-arm.cc b/src/ic/arm/ic-arm.cc index 129ab70cad..fad0737a1c 100644 --- a/src/ic/arm/ic-arm.cc +++ b/src/ic/arm/ic-arm.cc @@ -19,133 +19,6 @@ namespace internal { #define __ ACCESS_MASM(masm) -// Helper function used from LoadIC GenerateNormal. -// -// elements: Property dictionary. It is not clobbered if a jump to the miss -// label is done. -// name: Property name. It is not clobbered if a jump to the miss label is -// done -// result: Register for the result. It is only updated if a jump to the miss -// label is not done. Can be the same as elements or name clobbering -// one of these in the case of not jumping to the miss label. -// The two scratch registers need to be different from elements, name and -// result. -// The generated code assumes that the receiver has slow properties, -// is not a global object and does not have interceptors. -static void GenerateDictionaryLoad(MacroAssembler* masm, Label* miss, - Register elements, Register name, - Register result, Register scratch1, - Register scratch2) { - // Main use of the scratch registers. - // scratch1: Used as temporary and to hold the capacity of the property - // dictionary. - // scratch2: Used as temporary. - Label done; - - // Probe the dictionary. - NameDictionaryLookupStub::GeneratePositiveLookup(masm, miss, &done, elements, - name, scratch1, scratch2); - - // If probing finds an entry check that the value is a normal - // property. - __ bind(&done); // scratch2 == elements + 4 * index - const int kElementsStartOffset = - NameDictionary::kHeaderSize + - NameDictionary::kElementsStartIndex * kPointerSize; - const int kDetailsOffset = kElementsStartOffset + 2 * kPointerSize; - __ ldr(scratch1, FieldMemOperand(scratch2, kDetailsOffset)); - __ tst(scratch1, Operand(PropertyDetails::TypeField::kMask << kSmiTagSize)); - __ b(ne, miss); - - // Get the value at the masked, scaled index and return. - __ ldr(result, - FieldMemOperand(scratch2, kElementsStartOffset + 1 * kPointerSize)); -} - - -// Helper function used from StoreIC::GenerateNormal. -// -// elements: Property dictionary. It is not clobbered if a jump to the miss -// label is done. -// name: Property name. It is not clobbered if a jump to the miss label is -// done -// value: The value to store. -// The two scratch registers need to be different from elements, name and -// result. -// The generated code assumes that the receiver has slow properties, -// is not a global object and does not have interceptors. -static void GenerateDictionaryStore(MacroAssembler* masm, Label* miss, - Register elements, Register name, - Register value, Register scratch1, - Register scratch2) { - // Main use of the scratch registers. - // scratch1: Used as temporary and to hold the capacity of the property - // dictionary. - // scratch2: Used as temporary. - Label done; - - // Probe the dictionary. - NameDictionaryLookupStub::GeneratePositiveLookup(masm, miss, &done, elements, - name, scratch1, scratch2); - - // If probing finds an entry in the dictionary check that the value - // is a normal property that is not read only. - __ bind(&done); // scratch2 == elements + 4 * index - const int kElementsStartOffset = - NameDictionary::kHeaderSize + - NameDictionary::kElementsStartIndex * kPointerSize; - const int kDetailsOffset = kElementsStartOffset + 2 * kPointerSize; - const int kTypeAndReadOnlyMask = - (PropertyDetails::TypeField::kMask | - PropertyDetails::AttributesField::encode(READ_ONLY)) - << kSmiTagSize; - __ ldr(scratch1, FieldMemOperand(scratch2, kDetailsOffset)); - __ tst(scratch1, Operand(kTypeAndReadOnlyMask)); - __ b(ne, miss); - - // Store the value at the masked, scaled index and return. - const int kValueOffset = kElementsStartOffset + kPointerSize; - __ add(scratch2, scratch2, Operand(kValueOffset - kHeapObjectTag)); - __ str(value, MemOperand(scratch2)); - - // Update the write barrier. Make sure not to clobber the value. - __ mov(scratch1, value); - __ RecordWrite(elements, scratch2, scratch1, kLRHasNotBeenSaved, - kDontSaveFPRegs); -} - -void LoadIC::GenerateNormal(MacroAssembler* masm) { - Register dictionary = r0; - DCHECK(!dictionary.is(LoadDescriptor::ReceiverRegister())); - DCHECK(!dictionary.is(LoadDescriptor::NameRegister())); - - Label slow; - - __ ldr(dictionary, FieldMemOperand(LoadDescriptor::ReceiverRegister(), - JSObject::kPropertiesOffset)); - GenerateDictionaryLoad(masm, &slow, dictionary, - LoadDescriptor::NameRegister(), r0, r3, r4); - __ Ret(); - - // Dictionary load failed, go slow (but don't miss). - __ bind(&slow); - GenerateRuntimeGetProperty(masm); -} - - -// A register that isn't one of the parameters to the load ic. -static const Register LoadIC_TempRegister() { return r3; } - -void LoadIC::GenerateRuntimeGetProperty(MacroAssembler* masm) { - // The return address is in lr. - - __ mov(LoadIC_TempRegister(), LoadDescriptor::ReceiverRegister()); - __ Push(LoadIC_TempRegister(), LoadDescriptor::NameRegister()); - - // Do tail-call to runtime routine. - __ TailCallRuntime(Runtime::kGetProperty); -} - static void StoreIC_PushArgs(MacroAssembler* masm) { __ Push(StoreWithVectorDescriptor::ValueRegister(), StoreWithVectorDescriptor::SlotRegister(), @@ -169,39 +42,6 @@ void KeyedStoreIC::GenerateSlow(MacroAssembler* masm) { __ TailCallRuntime(Runtime::kKeyedStoreIC_Slow); } -void StoreIC::GenerateMiss(MacroAssembler* masm) { - StoreIC_PushArgs(masm); - - // Perform tail call to the entry. - __ TailCallRuntime(Runtime::kStoreIC_Miss); -} - - -void StoreIC::GenerateNormal(MacroAssembler* masm) { - Label miss; - Register receiver = StoreDescriptor::ReceiverRegister(); - Register name = StoreDescriptor::NameRegister(); - Register value = StoreDescriptor::ValueRegister(); - Register dictionary = r5; - DCHECK(receiver.is(r1)); - DCHECK(name.is(r2)); - DCHECK(value.is(r0)); - DCHECK(StoreWithVectorDescriptor::VectorRegister().is(r3)); - DCHECK(StoreWithVectorDescriptor::SlotRegister().is(r4)); - - __ ldr(dictionary, FieldMemOperand(receiver, JSObject::kPropertiesOffset)); - - GenerateDictionaryStore(masm, &miss, dictionary, name, value, r6, r9); - Counters* counters = masm->isolate()->counters(); - __ IncrementCounter(counters->ic_store_normal_hit(), 1, r6, r9); - __ Ret(); - - __ bind(&miss); - __ IncrementCounter(counters->ic_store_normal_miss(), 1, r6, r9); - GenerateMiss(masm); -} - - #undef __ diff --git a/src/ic/arm64/ic-arm64.cc b/src/ic/arm64/ic-arm64.cc index 7a330b3c3a..04fdff76e1 100644 --- a/src/ic/arm64/ic-arm64.cc +++ b/src/ic/arm64/ic-arm64.cc @@ -15,120 +15,6 @@ namespace internal { #define __ ACCESS_MASM(masm) -// Helper function used from LoadIC GenerateNormal. -// -// elements: Property dictionary. It is not clobbered if a jump to the miss -// label is done. -// name: Property name. It is not clobbered if a jump to the miss label is -// done -// result: Register for the result. It is only updated if a jump to the miss -// label is not done. -// The scratch registers need to be different from elements, name and result. -// The generated code assumes that the receiver has slow properties, -// is not a global object and does not have interceptors. -static void GenerateDictionaryLoad(MacroAssembler* masm, Label* miss, - Register elements, Register name, - Register result, Register scratch1, - Register scratch2) { - DCHECK(!AreAliased(elements, name, scratch1, scratch2)); - DCHECK(!AreAliased(result, scratch1, scratch2)); - - Label done; - - // Probe the dictionary. - NameDictionaryLookupStub::GeneratePositiveLookup(masm, miss, &done, elements, - name, scratch1, scratch2); - - // If probing finds an entry check that the value is a normal property. - __ Bind(&done); - - static const int kElementsStartOffset = - NameDictionary::kHeaderSize + - NameDictionary::kElementsStartIndex * kPointerSize; - static const int kDetailsOffset = kElementsStartOffset + 2 * kPointerSize; - __ Ldr(scratch1, FieldMemOperand(scratch2, kDetailsOffset)); - __ Tst(scratch1, Smi::FromInt(PropertyDetails::TypeField::kMask)); - __ B(ne, miss); - - // Get the value at the masked, scaled index and return. - __ Ldr(result, - FieldMemOperand(scratch2, kElementsStartOffset + 1 * kPointerSize)); -} - - -// Helper function used from StoreIC::GenerateNormal. -// -// elements: Property dictionary. It is not clobbered if a jump to the miss -// label is done. -// name: Property name. It is not clobbered if a jump to the miss label is -// done -// value: The value to store (never clobbered). -// -// The generated code assumes that the receiver has slow properties, -// is not a global object and does not have interceptors. -static void GenerateDictionaryStore(MacroAssembler* masm, Label* miss, - Register elements, Register name, - Register value, Register scratch1, - Register scratch2) { - DCHECK(!AreAliased(elements, name, value, scratch1, scratch2)); - - Label done; - - // Probe the dictionary. - NameDictionaryLookupStub::GeneratePositiveLookup(masm, miss, &done, elements, - name, scratch1, scratch2); - - // If probing finds an entry in the dictionary check that the value - // is a normal property that is not read only. - __ Bind(&done); - - static const int kElementsStartOffset = - NameDictionary::kHeaderSize + - NameDictionary::kElementsStartIndex * kPointerSize; - static const int kDetailsOffset = kElementsStartOffset + 2 * kPointerSize; - static const int kTypeAndReadOnlyMask = - PropertyDetails::TypeField::kMask | - PropertyDetails::AttributesField::encode(READ_ONLY); - __ Ldrsw(scratch1, UntagSmiFieldMemOperand(scratch2, kDetailsOffset)); - __ Tst(scratch1, kTypeAndReadOnlyMask); - __ B(ne, miss); - - // Store the value at the masked, scaled index and return. - static const int kValueOffset = kElementsStartOffset + kPointerSize; - __ Add(scratch2, scratch2, kValueOffset - kHeapObjectTag); - __ Str(value, MemOperand(scratch2)); - - // Update the write barrier. Make sure not to clobber the value. - __ Mov(scratch1, value); - __ RecordWrite(elements, scratch2, scratch1, kLRHasNotBeenSaved, - kDontSaveFPRegs); -} - -void LoadIC::GenerateNormal(MacroAssembler* masm) { - Register dictionary = x0; - DCHECK(!dictionary.is(LoadDescriptor::ReceiverRegister())); - DCHECK(!dictionary.is(LoadDescriptor::NameRegister())); - Label slow; - - __ Ldr(dictionary, FieldMemOperand(LoadDescriptor::ReceiverRegister(), - JSObject::kPropertiesOffset)); - GenerateDictionaryLoad(masm, &slow, dictionary, - LoadDescriptor::NameRegister(), x0, x3, x4); - __ Ret(); - - // Dictionary load failed, go slow (but don't miss). - __ Bind(&slow); - GenerateRuntimeGetProperty(masm); -} - -void LoadIC::GenerateRuntimeGetProperty(MacroAssembler* masm) { - // The return address is in lr. - __ Push(LoadDescriptor::ReceiverRegister(), LoadDescriptor::NameRegister()); - - // Do tail-call to runtime routine. - __ TailCallRuntime(Runtime::kGetProperty); -} - static void StoreIC_PushArgs(MacroAssembler* masm) { __ Push(StoreWithVectorDescriptor::ValueRegister(), StoreWithVectorDescriptor::SlotRegister(), @@ -153,38 +39,6 @@ void KeyedStoreIC::GenerateSlow(MacroAssembler* masm) { __ TailCallRuntime(Runtime::kKeyedStoreIC_Slow); } -void StoreIC::GenerateMiss(MacroAssembler* masm) { - StoreIC_PushArgs(masm); - - // Tail call to the entry. - __ TailCallRuntime(Runtime::kStoreIC_Miss); -} - - -void StoreIC::GenerateNormal(MacroAssembler* masm) { - Label miss; - Register value = StoreDescriptor::ValueRegister(); - Register receiver = StoreDescriptor::ReceiverRegister(); - Register name = StoreDescriptor::NameRegister(); - Register dictionary = x5; - DCHECK(!AreAliased(value, receiver, name, - StoreWithVectorDescriptor::SlotRegister(), - StoreWithVectorDescriptor::VectorRegister(), x5, x6, x7)); - - __ Ldr(dictionary, FieldMemOperand(receiver, JSObject::kPropertiesOffset)); - - GenerateDictionaryStore(masm, &miss, dictionary, name, value, x6, x7); - Counters* counters = masm->isolate()->counters(); - __ IncrementCounter(counters->ic_store_normal_hit(), 1, x6, x7); - __ Ret(); - - // Cache miss: Jump to runtime. - __ Bind(&miss); - __ IncrementCounter(counters->ic_store_normal_miss(), 1, x6, x7); - GenerateMiss(masm); -} - - Condition CompareIC::ComputeCondition(Token::Value op) { switch (op) { case Token::EQ_STRICT: diff --git a/src/ic/ia32/ic-ia32.cc b/src/ic/ia32/ic-ia32.cc index b9360ced91..4bf0eaee92 100644 --- a/src/ic/ia32/ic-ia32.cc +++ b/src/ic/ia32/ic-ia32.cc @@ -18,141 +18,6 @@ namespace internal { #define __ ACCESS_MASM(masm) -// Helper function used to load a property from a dictionary backing -// storage. This function may fail to load a property even though it is -// in the dictionary, so code at miss_label must always call a backup -// property load that is complete. This function is safe to call if -// name is not internalized, and will jump to the miss_label in that -// case. The generated code assumes that the receiver has slow -// properties, is not a global object and does not have interceptors. -static void GenerateDictionaryLoad(MacroAssembler* masm, Label* miss_label, - Register elements, Register name, - Register r0, Register r1, Register result) { - // Register use: - // - // elements - holds the property dictionary on entry and is unchanged. - // - // name - holds the name of the property on entry and is unchanged. - // - // Scratch registers: - // - // r0 - used for the index into the property dictionary - // - // r1 - used to hold the capacity of the property dictionary. - // - // result - holds the result on exit. - - Label done; - - // Probe the dictionary. - NameDictionaryLookupStub::GeneratePositiveLookup(masm, miss_label, &done, - elements, name, r0, r1); - - // If probing finds an entry in the dictionary, r0 contains the - // index into the dictionary. Check that the value is a normal - // property. - __ bind(&done); - const int kElementsStartOffset = - NameDictionary::kHeaderSize + - NameDictionary::kElementsStartIndex * kPointerSize; - const int kDetailsOffset = kElementsStartOffset + 2 * kPointerSize; - __ test(Operand(elements, r0, times_4, kDetailsOffset - kHeapObjectTag), - Immediate(PropertyDetails::TypeField::kMask << kSmiTagSize)); - __ j(not_zero, miss_label); - - // Get the value at the masked, scaled index. - const int kValueOffset = kElementsStartOffset + kPointerSize; - __ mov(result, Operand(elements, r0, times_4, kValueOffset - kHeapObjectTag)); -} - - -// Helper function used to store a property to a dictionary backing -// storage. This function may fail to store a property eventhough it -// is in the dictionary, so code at miss_label must always call a -// backup property store that is complete. This function is safe to -// call if name is not internalized, and will jump to the miss_label in -// that case. The generated code assumes that the receiver has slow -// properties, is not a global object and does not have interceptors. -static void GenerateDictionaryStore(MacroAssembler* masm, Label* miss_label, - Register elements, Register name, - Register value, Register r0, Register r1) { - // Register use: - // - // elements - holds the property dictionary on entry and is clobbered. - // - // name - holds the name of the property on entry and is unchanged. - // - // value - holds the value to store and is unchanged. - // - // r0 - used for index into the property dictionary and is clobbered. - // - // r1 - used to hold the capacity of the property dictionary and is clobbered. - Label done; - - - // Probe the dictionary. - NameDictionaryLookupStub::GeneratePositiveLookup(masm, miss_label, &done, - elements, name, r0, r1); - - // If probing finds an entry in the dictionary, r0 contains the - // index into the dictionary. Check that the value is a normal - // property that is not read only. - __ bind(&done); - const int kElementsStartOffset = - NameDictionary::kHeaderSize + - NameDictionary::kElementsStartIndex * kPointerSize; - const int kDetailsOffset = kElementsStartOffset + 2 * kPointerSize; - const int kTypeAndReadOnlyMask = - (PropertyDetails::TypeField::kMask | - PropertyDetails::AttributesField::encode(READ_ONLY)) - << kSmiTagSize; - __ test(Operand(elements, r0, times_4, kDetailsOffset - kHeapObjectTag), - Immediate(kTypeAndReadOnlyMask)); - __ j(not_zero, miss_label); - - // Store the value at the masked, scaled index. - const int kValueOffset = kElementsStartOffset + kPointerSize; - __ lea(r0, Operand(elements, r0, times_4, kValueOffset - kHeapObjectTag)); - __ mov(Operand(r0, 0), value); - - // Update write barrier. Make sure not to clobber the value. - __ mov(r1, value); - __ RecordWrite(elements, r0, r1, kDontSaveFPRegs); -} - -void LoadIC::GenerateNormal(MacroAssembler* masm) { - Register dictionary = eax; - DCHECK(!dictionary.is(LoadDescriptor::ReceiverRegister())); - DCHECK(!dictionary.is(LoadDescriptor::NameRegister())); - - Label slow; - - __ mov(dictionary, FieldOperand(LoadDescriptor::ReceiverRegister(), - JSObject::kPropertiesOffset)); - GenerateDictionaryLoad(masm, &slow, dictionary, - LoadDescriptor::NameRegister(), edi, ebx, eax); - __ ret(0); - - // Dictionary load failed, go slow (but don't miss). - __ bind(&slow); - GenerateRuntimeGetProperty(masm); -} - -void LoadIC::GenerateRuntimeGetProperty(MacroAssembler* masm) { - // Return address is on the stack. - Register receiver = LoadDescriptor::ReceiverRegister(); - Register name = LoadDescriptor::NameRegister(); - DCHECK(!ebx.is(receiver) && !ebx.is(name)); - - __ pop(ebx); - __ push(receiver); - __ push(name); - __ push(ebx); - - // Do tail-call to runtime routine. - __ TailCallRuntime(Runtime::kGetProperty); -} - static void StoreIC_PushArgs(MacroAssembler* masm) { Register receiver = StoreWithVectorDescriptor::ReceiverRegister(); Register name = StoreWithVectorDescriptor::NameRegister(); @@ -171,50 +36,6 @@ static void StoreIC_PushArgs(MacroAssembler* masm) { __ push(return_address); } - -void StoreIC::GenerateMiss(MacroAssembler* masm) { - // Return address is on the stack. - StoreIC_PushArgs(masm); - - // Perform tail call to the entry. - __ TailCallRuntime(Runtime::kStoreIC_Miss); -} - - -void StoreIC::GenerateNormal(MacroAssembler* masm) { - typedef StoreWithVectorDescriptor Descriptor; - Label restore_miss; - Register receiver = Descriptor::ReceiverRegister(); - Register name = Descriptor::NameRegister(); - Register value = Descriptor::ValueRegister(); - // Since the slot and vector values are passed on the stack we can use - // respective registers as scratch registers. - Register scratch1 = Descriptor::VectorRegister(); - Register scratch2 = Descriptor::SlotRegister(); - - __ LoadParameterFromStack(value, Descriptor::kValue); - - // A lot of registers are needed for storing to slow case objects. - // Push and restore receiver but rely on GenerateDictionaryStore preserving - // the value and name. - __ push(receiver); - - Register dictionary = receiver; - __ mov(dictionary, FieldOperand(receiver, JSObject::kPropertiesOffset)); - GenerateDictionaryStore(masm, &restore_miss, dictionary, name, value, - scratch1, scratch2); - __ Drop(1); - Counters* counters = masm->isolate()->counters(); - __ IncrementCounter(counters->ic_store_normal_hit(), 1); - __ ret(Descriptor::kStackArgumentsCount * kPointerSize); - - __ bind(&restore_miss); - __ pop(receiver); - __ IncrementCounter(counters->ic_store_normal_miss(), 1); - GenerateMiss(masm); -} - - void KeyedStoreIC::GenerateMiss(MacroAssembler* masm) { // Return address is on the stack. StoreIC_PushArgs(masm); diff --git a/src/ic/ic.h b/src/ic/ic.h index 10081272d6..c86fd713a2 100644 --- a/src/ic/ic.h +++ b/src/ic/ic.h @@ -285,10 +285,6 @@ class LoadIC : public IC { NOT_INSIDE_TYPEOF; } - // Code generator routines. - static void GenerateRuntimeGetProperty(MacroAssembler* masm); - static void GenerateNormal(MacroAssembler* masm); - MUST_USE_RESULT MaybeHandle Load(Handle object, Handle name); @@ -374,11 +370,6 @@ class StoreIC : public IC { return StoreICState::GetLanguageMode(extra_ic_state()); } - // Code generators for stub routines. Only called once at startup. - static void GenerateSlow(MacroAssembler* masm); - static void GenerateMiss(MacroAssembler* masm); - static void GenerateNormal(MacroAssembler* masm); - MUST_USE_RESULT MaybeHandle Store( Handle object, Handle name, Handle value, JSReceiver::StoreFromKeyed store_mode = diff --git a/src/ic/mips/ic-mips.cc b/src/ic/mips/ic-mips.cc index 4ddf75e302..e31aab1d76 100644 --- a/src/ic/mips/ic-mips.cc +++ b/src/ic/mips/ic-mips.cc @@ -19,138 +19,6 @@ namespace internal { #define __ ACCESS_MASM(masm) -// Helper function used from LoadIC GenerateNormal. -// -// elements: Property dictionary. It is not clobbered if a jump to the miss -// label is done. -// name: Property name. It is not clobbered if a jump to the miss label is -// done -// result: Register for the result. It is only updated if a jump to the miss -// label is not done. Can be the same as elements or name clobbering -// one of these in the case of not jumping to the miss label. -// The two scratch registers need to be different from elements, name and -// result. -// The generated code assumes that the receiver has slow properties, -// is not a global object and does not have interceptors. -// The address returned from GenerateStringDictionaryProbes() in scratch2 -// is used. -static void GenerateDictionaryLoad(MacroAssembler* masm, Label* miss, - Register elements, Register name, - Register result, Register scratch1, - Register scratch2) { - // Main use of the scratch registers. - // scratch1: Used as temporary and to hold the capacity of the property - // dictionary. - // scratch2: Used as temporary. - Label done; - - // Probe the dictionary. - NameDictionaryLookupStub::GeneratePositiveLookup(masm, miss, &done, elements, - name, scratch1, scratch2); - - // If probing finds an entry check that the value is a normal - // property. - __ bind(&done); // scratch2 == elements + 4 * index. - const int kElementsStartOffset = - NameDictionary::kHeaderSize + - NameDictionary::kElementsStartIndex * kPointerSize; - const int kDetailsOffset = kElementsStartOffset + 2 * kPointerSize; - __ lw(scratch1, FieldMemOperand(scratch2, kDetailsOffset)); - __ And(at, scratch1, - Operand(PropertyDetails::TypeField::kMask << kSmiTagSize)); - __ Branch(miss, ne, at, Operand(zero_reg)); - - // Get the value at the masked, scaled index and return. - __ lw(result, - FieldMemOperand(scratch2, kElementsStartOffset + 1 * kPointerSize)); -} - - -// Helper function used from StoreIC::GenerateNormal. -// -// elements: Property dictionary. It is not clobbered if a jump to the miss -// label is done. -// name: Property name. It is not clobbered if a jump to the miss label is -// done -// value: The value to store. -// The two scratch registers need to be different from elements, name and -// result. -// The generated code assumes that the receiver has slow properties, -// is not a global object and does not have interceptors. -// The address returned from GenerateStringDictionaryProbes() in scratch2 -// is used. -static void GenerateDictionaryStore(MacroAssembler* masm, Label* miss, - Register elements, Register name, - Register value, Register scratch1, - Register scratch2) { - // Main use of the scratch registers. - // scratch1: Used as temporary and to hold the capacity of the property - // dictionary. - // scratch2: Used as temporary. - Label done; - - // Probe the dictionary. - NameDictionaryLookupStub::GeneratePositiveLookup(masm, miss, &done, elements, - name, scratch1, scratch2); - - // If probing finds an entry in the dictionary check that the value - // is a normal property that is not read only. - __ bind(&done); // scratch2 == elements + 4 * index. - const int kElementsStartOffset = - NameDictionary::kHeaderSize + - NameDictionary::kElementsStartIndex * kPointerSize; - const int kDetailsOffset = kElementsStartOffset + 2 * kPointerSize; - const int kTypeAndReadOnlyMask = - (PropertyDetails::TypeField::kMask | - PropertyDetails::AttributesField::encode(READ_ONLY)) - << kSmiTagSize; - __ lw(scratch1, FieldMemOperand(scratch2, kDetailsOffset)); - __ And(at, scratch1, Operand(kTypeAndReadOnlyMask)); - __ Branch(miss, ne, at, Operand(zero_reg)); - - // Store the value at the masked, scaled index and return. - const int kValueOffset = kElementsStartOffset + kPointerSize; - __ Addu(scratch2, scratch2, Operand(kValueOffset - kHeapObjectTag)); - __ sw(value, MemOperand(scratch2)); - - // Update the write barrier. Make sure not to clobber the value. - __ mov(scratch1, value); - __ RecordWrite(elements, scratch2, scratch1, kRAHasNotBeenSaved, - kDontSaveFPRegs); -} - -void LoadIC::GenerateNormal(MacroAssembler* masm) { - Register dictionary = a0; - DCHECK(!dictionary.is(LoadDescriptor::ReceiverRegister())); - DCHECK(!dictionary.is(LoadDescriptor::NameRegister())); - - Label slow; - - __ lw(dictionary, FieldMemOperand(LoadDescriptor::ReceiverRegister(), - JSObject::kPropertiesOffset)); - GenerateDictionaryLoad(masm, &slow, dictionary, - LoadDescriptor::NameRegister(), v0, a3, t0); - __ Ret(); - - // Dictionary load failed, go slow (but don't miss). - __ bind(&slow); - GenerateRuntimeGetProperty(masm); -} - - -// A register that isn't one of the parameters to the load ic. -static const Register LoadIC_TempRegister() { return a3; } - -void LoadIC::GenerateRuntimeGetProperty(MacroAssembler* masm) { - // The return address is in ra. - - __ mov(LoadIC_TempRegister(), LoadDescriptor::ReceiverRegister()); - __ Push(LoadIC_TempRegister(), LoadDescriptor::NameRegister()); - - // Do tail-call to runtime routine. - __ TailCallRuntime(Runtime::kGetProperty); -} - static void StoreIC_PushArgs(MacroAssembler* masm) { __ Push(StoreWithVectorDescriptor::ValueRegister(), StoreWithVectorDescriptor::SlotRegister(), @@ -174,40 +42,6 @@ void KeyedStoreIC::GenerateSlow(MacroAssembler* masm) { __ TailCallRuntime(Runtime::kKeyedStoreIC_Slow); } -void StoreIC::GenerateMiss(MacroAssembler* masm) { - StoreIC_PushArgs(masm); - - // Perform tail call to the entry. - __ TailCallRuntime(Runtime::kStoreIC_Miss); -} - - -void StoreIC::GenerateNormal(MacroAssembler* masm) { - Label miss; - Register receiver = StoreDescriptor::ReceiverRegister(); - Register name = StoreDescriptor::NameRegister(); - Register value = StoreDescriptor::ValueRegister(); - Register dictionary = t1; - DCHECK(receiver.is(a1)); - DCHECK(name.is(a2)); - DCHECK(value.is(a0)); - DCHECK(StoreWithVectorDescriptor::VectorRegister().is(a3)); - DCHECK(StoreWithVectorDescriptor::SlotRegister().is(t0)); - - __ lw(dictionary, FieldMemOperand(receiver, JSObject::kPropertiesOffset)); - - GenerateDictionaryStore(masm, &miss, dictionary, name, value, t2, t5); - Counters* counters = masm->isolate()->counters(); - __ IncrementCounter(counters->ic_store_normal_hit(), 1, t2, t5); - __ Ret(USE_DELAY_SLOT); - __ Move(v0, value); // Ensure the stub returns correct value. - - __ bind(&miss); - __ IncrementCounter(counters->ic_store_normal_miss(), 1, t2, t5); - GenerateMiss(masm); -} - - #undef __ diff --git a/src/ic/mips64/ic-mips64.cc b/src/ic/mips64/ic-mips64.cc index 14b1b9b6c2..fa351ba5a3 100644 --- a/src/ic/mips64/ic-mips64.cc +++ b/src/ic/mips64/ic-mips64.cc @@ -19,136 +19,6 @@ namespace internal { #define __ ACCESS_MASM(masm) -// Helper function used from LoadIC GenerateNormal. -// -// elements: Property dictionary. It is not clobbered if a jump to the miss -// label is done. -// name: Property name. It is not clobbered if a jump to the miss label is -// done -// result: Register for the result. It is only updated if a jump to the miss -// label is not done. Can be the same as elements or name clobbering -// one of these in the case of not jumping to the miss label. -// The two scratch registers need to be different from elements, name and -// result. -// The generated code assumes that the receiver has slow properties, -// is not a global object and does not have interceptors. -// The address returned from GenerateStringDictionaryProbes() in scratch2 -// is used. -static void GenerateDictionaryLoad(MacroAssembler* masm, Label* miss, - Register elements, Register name, - Register result, Register scratch1, - Register scratch2) { - // Main use of the scratch registers. - // scratch1: Used as temporary and to hold the capacity of the property - // dictionary. - // scratch2: Used as temporary. - Label done; - - // Probe the dictionary. - NameDictionaryLookupStub::GeneratePositiveLookup(masm, miss, &done, elements, - name, scratch1, scratch2); - - // If probing finds an entry check that the value is a normal - // property. - __ bind(&done); // scratch2 == elements + 4 * index. - const int kElementsStartOffset = - NameDictionary::kHeaderSize + - NameDictionary::kElementsStartIndex * kPointerSize; - const int kDetailsOffset = kElementsStartOffset + 2 * kPointerSize; - __ ld(scratch1, FieldMemOperand(scratch2, kDetailsOffset)); - __ And(at, scratch1, - Operand(Smi::FromInt(PropertyDetails::TypeField::kMask))); - __ Branch(miss, ne, at, Operand(zero_reg)); - - // Get the value at the masked, scaled index and return. - __ ld(result, - FieldMemOperand(scratch2, kElementsStartOffset + 1 * kPointerSize)); -} - - -// Helper function used from StoreIC::GenerateNormal. -// -// elements: Property dictionary. It is not clobbered if a jump to the miss -// label is done. -// name: Property name. It is not clobbered if a jump to the miss label is -// done -// value: The value to store. -// The two scratch registers need to be different from elements, name and -// result. -// The generated code assumes that the receiver has slow properties, -// is not a global object and does not have interceptors. -// The address returned from GenerateStringDictionaryProbes() in scratch2 -// is used. -static void GenerateDictionaryStore(MacroAssembler* masm, Label* miss, - Register elements, Register name, - Register value, Register scratch1, - Register scratch2) { - // Main use of the scratch registers. - // scratch1: Used as temporary and to hold the capacity of the property - // dictionary. - // scratch2: Used as temporary. - Label done; - - // Probe the dictionary. - NameDictionaryLookupStub::GeneratePositiveLookup(masm, miss, &done, elements, - name, scratch1, scratch2); - - // If probing finds an entry in the dictionary check that the value - // is a normal property that is not read only. - __ bind(&done); // scratch2 == elements + 4 * index. - const int kElementsStartOffset = - NameDictionary::kHeaderSize + - NameDictionary::kElementsStartIndex * kPointerSize; - const int kDetailsOffset = kElementsStartOffset + 2 * kPointerSize; - const int kTypeAndReadOnlyMask = - (PropertyDetails::TypeField::kMask | - PropertyDetails::AttributesField::encode(READ_ONLY)); - __ ld(scratch1, FieldMemOperand(scratch2, kDetailsOffset)); - __ And(at, scratch1, Operand(Smi::FromInt(kTypeAndReadOnlyMask))); - __ Branch(miss, ne, at, Operand(zero_reg)); - - // Store the value at the masked, scaled index and return. - const int kValueOffset = kElementsStartOffset + kPointerSize; - __ Daddu(scratch2, scratch2, Operand(kValueOffset - kHeapObjectTag)); - __ sd(value, MemOperand(scratch2)); - - // Update the write barrier. Make sure not to clobber the value. - __ mov(scratch1, value); - __ RecordWrite(elements, scratch2, scratch1, kRAHasNotBeenSaved, - kDontSaveFPRegs); -} - -void LoadIC::GenerateNormal(MacroAssembler* masm) { - Register dictionary = a0; - DCHECK(!dictionary.is(LoadDescriptor::ReceiverRegister())); - DCHECK(!dictionary.is(LoadDescriptor::NameRegister())); - Label slow; - - __ ld(dictionary, FieldMemOperand(LoadDescriptor::ReceiverRegister(), - JSObject::kPropertiesOffset)); - GenerateDictionaryLoad(masm, &slow, dictionary, - LoadDescriptor::NameRegister(), v0, a3, a4); - __ Ret(); - - // Dictionary load failed, go slow (but don't miss). - __ bind(&slow); - GenerateRuntimeGetProperty(masm); -} - - -// A register that isn't one of the parameters to the load ic. -static const Register LoadIC_TempRegister() { return a3; } - -void LoadIC::GenerateRuntimeGetProperty(MacroAssembler* masm) { - // The return address is in ra. - - __ mov(LoadIC_TempRegister(), LoadDescriptor::ReceiverRegister()); - __ Push(LoadIC_TempRegister(), LoadDescriptor::NameRegister()); - - // Do tail-call to runtime routine. - __ TailCallRuntime(Runtime::kGetProperty); -} - static void StoreIC_PushArgs(MacroAssembler* masm) { __ Push(StoreWithVectorDescriptor::ValueRegister(), StoreWithVectorDescriptor::SlotRegister(), @@ -172,38 +42,6 @@ void KeyedStoreIC::GenerateSlow(MacroAssembler* masm) { __ TailCallRuntime(Runtime::kKeyedStoreIC_Slow); } -void StoreIC::GenerateMiss(MacroAssembler* masm) { - StoreIC_PushArgs(masm); - - // Perform tail call to the entry. - __ TailCallRuntime(Runtime::kStoreIC_Miss); -} - - -void StoreIC::GenerateNormal(MacroAssembler* masm) { - Label miss; - Register receiver = StoreDescriptor::ReceiverRegister(); - Register name = StoreDescriptor::NameRegister(); - Register value = StoreDescriptor::ValueRegister(); - Register dictionary = a5; - DCHECK(!AreAliased( - value, receiver, name, StoreWithVectorDescriptor::VectorRegister(), - StoreWithVectorDescriptor::SlotRegister(), dictionary, a6, a7)); - - __ ld(dictionary, FieldMemOperand(receiver, JSObject::kPropertiesOffset)); - - GenerateDictionaryStore(masm, &miss, dictionary, name, value, a6, a7); - Counters* counters = masm->isolate()->counters(); - __ IncrementCounter(counters->ic_store_normal_hit(), 1, a6, a7); - __ Ret(USE_DELAY_SLOT); - __ Move(v0, value); // Ensure the stub returns correct value. - - __ bind(&miss); - __ IncrementCounter(counters->ic_store_normal_miss(), 1, a6, a7); - GenerateMiss(masm); -} - - #undef __ diff --git a/src/ic/ppc/ic-ppc.cc b/src/ic/ppc/ic-ppc.cc index 40fcbe900c..3c325d8f92 100644 --- a/src/ic/ppc/ic-ppc.cc +++ b/src/ic/ppc/ic-ppc.cc @@ -19,138 +19,6 @@ namespace internal { #define __ ACCESS_MASM(masm) -// Helper function used from LoadIC GenerateNormal. -// -// elements: Property dictionary. It is not clobbered if a jump to the miss -// label is done. -// name: Property name. It is not clobbered if a jump to the miss label is -// done -// result: Register for the result. It is only updated if a jump to the miss -// label is not done. Can be the same as elements or name clobbering -// one of these in the case of not jumping to the miss label. -// The two scratch registers need to be different from elements, name and -// result. -// The generated code assumes that the receiver has slow properties, -// is not a global object and does not have interceptors. -static void GenerateDictionaryLoad(MacroAssembler* masm, Label* miss, - Register elements, Register name, - Register result, Register scratch1, - Register scratch2) { - // Main use of the scratch registers. - // scratch1: Used as temporary and to hold the capacity of the property - // dictionary. - // scratch2: Used as temporary. - Label done; - - // Probe the dictionary. - NameDictionaryLookupStub::GeneratePositiveLookup(masm, miss, &done, elements, - name, scratch1, scratch2); - - // If probing finds an entry check that the value is a normal - // property. - __ bind(&done); // scratch2 == elements + 4 * index - const int kElementsStartOffset = - NameDictionary::kHeaderSize + - NameDictionary::kElementsStartIndex * kPointerSize; - const int kDetailsOffset = kElementsStartOffset + 2 * kPointerSize; - __ LoadP(scratch1, FieldMemOperand(scratch2, kDetailsOffset)); - __ mr(r0, scratch2); - __ LoadSmiLiteral(scratch2, Smi::FromInt(PropertyDetails::TypeField::kMask)); - __ and_(scratch2, scratch1, scratch2, SetRC); - __ bne(miss, cr0); - __ mr(scratch2, r0); - - // Get the value at the masked, scaled index and return. - __ LoadP(result, - FieldMemOperand(scratch2, kElementsStartOffset + 1 * kPointerSize)); -} - - -// Helper function used from StoreIC::GenerateNormal. -// -// elements: Property dictionary. It is not clobbered if a jump to the miss -// label is done. -// name: Property name. It is not clobbered if a jump to the miss label is -// done -// value: The value to store. -// The two scratch registers need to be different from elements, name and -// result. -// The generated code assumes that the receiver has slow properties, -// is not a global object and does not have interceptors. -static void GenerateDictionaryStore(MacroAssembler* masm, Label* miss, - Register elements, Register name, - Register value, Register scratch1, - Register scratch2) { - // Main use of the scratch registers. - // scratch1: Used as temporary and to hold the capacity of the property - // dictionary. - // scratch2: Used as temporary. - Label done; - - // Probe the dictionary. - NameDictionaryLookupStub::GeneratePositiveLookup(masm, miss, &done, elements, - name, scratch1, scratch2); - - // If probing finds an entry in the dictionary check that the value - // is a normal property that is not read only. - __ bind(&done); // scratch2 == elements + 4 * index - const int kElementsStartOffset = - NameDictionary::kHeaderSize + - NameDictionary::kElementsStartIndex * kPointerSize; - const int kDetailsOffset = kElementsStartOffset + 2 * kPointerSize; - int kTypeAndReadOnlyMask = - PropertyDetails::TypeField::kMask | - PropertyDetails::AttributesField::encode(READ_ONLY); - __ LoadP(scratch1, FieldMemOperand(scratch2, kDetailsOffset)); - __ mr(r0, scratch2); - __ LoadSmiLiteral(scratch2, Smi::FromInt(kTypeAndReadOnlyMask)); - __ and_(scratch2, scratch1, scratch2, SetRC); - __ bne(miss, cr0); - __ mr(scratch2, r0); - - // Store the value at the masked, scaled index and return. - const int kValueOffset = kElementsStartOffset + kPointerSize; - __ addi(scratch2, scratch2, Operand(kValueOffset - kHeapObjectTag)); - __ StoreP(value, MemOperand(scratch2)); - - // Update the write barrier. Make sure not to clobber the value. - __ mr(scratch1, value); - __ RecordWrite(elements, scratch2, scratch1, kLRHasNotBeenSaved, - kDontSaveFPRegs); -} - -void LoadIC::GenerateNormal(MacroAssembler* masm) { - Register dictionary = r3; - DCHECK(!dictionary.is(LoadDescriptor::ReceiverRegister())); - DCHECK(!dictionary.is(LoadDescriptor::NameRegister())); - - Label slow; - - __ LoadP(dictionary, FieldMemOperand(LoadDescriptor::ReceiverRegister(), - JSObject::kPropertiesOffset)); - GenerateDictionaryLoad(masm, &slow, dictionary, - LoadDescriptor::NameRegister(), r3, r6, r7); - __ Ret(); - - // Dictionary load failed, go slow (but don't miss). - __ bind(&slow); - GenerateRuntimeGetProperty(masm); -} - - -// A register that isn't one of the parameters to the load ic. -static const Register LoadIC_TempRegister() { return r6; } - -void LoadIC::GenerateRuntimeGetProperty(MacroAssembler* masm) { - // The return address is in lr. - - __ mr(LoadIC_TempRegister(), LoadDescriptor::ReceiverRegister()); - __ Push(LoadIC_TempRegister(), LoadDescriptor::NameRegister()); - - // Do tail-call to runtime routine. - __ TailCallRuntime(Runtime::kGetProperty); -} - static void StoreIC_PushArgs(MacroAssembler* masm) { __ Push(StoreWithVectorDescriptor::ValueRegister(), StoreWithVectorDescriptor::SlotRegister(), @@ -174,39 +42,6 @@ void KeyedStoreIC::GenerateSlow(MacroAssembler* masm) { __ TailCallRuntime(Runtime::kKeyedStoreIC_Slow); } -void StoreIC::GenerateMiss(MacroAssembler* masm) { - StoreIC_PushArgs(masm); - - // Perform tail call to the entry. - __ TailCallRuntime(Runtime::kStoreIC_Miss); -} - - -void StoreIC::GenerateNormal(MacroAssembler* masm) { - Label miss; - Register receiver = StoreDescriptor::ReceiverRegister(); - Register name = StoreDescriptor::NameRegister(); - Register value = StoreDescriptor::ValueRegister(); - Register dictionary = r8; - DCHECK(receiver.is(r4)); - DCHECK(name.is(r5)); - DCHECK(value.is(r3)); - DCHECK(StoreWithVectorDescriptor::VectorRegister().is(r6)); - DCHECK(StoreWithVectorDescriptor::SlotRegister().is(r7)); - - __ LoadP(dictionary, FieldMemOperand(receiver, JSObject::kPropertiesOffset)); - - GenerateDictionaryStore(masm, &miss, dictionary, name, value, r9, r10); - Counters* counters = masm->isolate()->counters(); - __ IncrementCounter(counters->ic_store_normal_hit(), 1, r9, r10); - __ Ret(); - - __ bind(&miss); - __ IncrementCounter(counters->ic_store_normal_miss(), 1, r9, r10); - GenerateMiss(masm); -} - - #undef __ diff --git a/src/ic/s390/ic-s390.cc b/src/ic/s390/ic-s390.cc index ba1769b0b2..6438cfca47 100644 --- a/src/ic/s390/ic-s390.cc +++ b/src/ic/s390/ic-s390.cc @@ -18,136 +18,6 @@ namespace internal { #define __ ACCESS_MASM(masm) -// Helper function used from LoadIC GenerateNormal. -// -// elements: Property dictionary. It is not clobbered if a jump to the miss -// label is done. -// name: Property name. It is not clobbered if a jump to the miss label is -// done -// result: Register for the result. It is only updated if a jump to the miss -// label is not done. Can be the same as elements or name clobbering -// one of these in the case of not jumping to the miss label. -// The two scratch registers need to be different from elements, name and -// result. -// The generated code assumes that the receiver has slow properties, -// is not a global object and does not have interceptors. -static void GenerateDictionaryLoad(MacroAssembler* masm, Label* miss, - Register elements, Register name, - Register result, Register scratch1, - Register scratch2) { - // Main use of the scratch registers. - // scratch1: Used as temporary and to hold the capacity of the property - // dictionary. - // scratch2: Used as temporary. - Label done; - - // Probe the dictionary. - NameDictionaryLookupStub::GeneratePositiveLookup(masm, miss, &done, elements, - name, scratch1, scratch2); - - // If probing finds an entry check that the value is a normal - // property. - __ bind(&done); // scratch2 == elements + 4 * index - const int kElementsStartOffset = - NameDictionary::kHeaderSize + - NameDictionary::kElementsStartIndex * kPointerSize; - const int kDetailsOffset = kElementsStartOffset + 2 * kPointerSize; - __ LoadP(scratch1, FieldMemOperand(scratch2, kDetailsOffset)); - __ LoadRR(r0, scratch2); - __ LoadSmiLiteral(scratch2, Smi::FromInt(PropertyDetails::TypeField::kMask)); - __ AndP(scratch2, scratch1); - __ bne(miss); - __ LoadRR(scratch2, r0); - - // Get the value at the masked, scaled index and return. - __ LoadP(result, - FieldMemOperand(scratch2, kElementsStartOffset + 1 * kPointerSize)); -} - -// Helper function used from StoreIC::GenerateNormal. -// -// elements: Property dictionary. It is not clobbered if a jump to the miss -// label is done. -// name: Property name. It is not clobbered if a jump to the miss label is -// done -// value: The value to store. -// The two scratch registers need to be different from elements, name and -// result. -// The generated code assumes that the receiver has slow properties, -// is not a global object and does not have interceptors. -static void GenerateDictionaryStore(MacroAssembler* masm, Label* miss, - Register elements, Register name, - Register value, Register scratch1, - Register scratch2) { - // Main use of the scratch registers. - // scratch1: Used as temporary and to hold the capacity of the property - // dictionary. - // scratch2: Used as temporary. - Label done; - - // Probe the dictionary. - NameDictionaryLookupStub::GeneratePositiveLookup(masm, miss, &done, elements, - name, scratch1, scratch2); - - // If probing finds an entry in the dictionary check that the value - // is a normal property that is not read only. - __ bind(&done); // scratch2 == elements + 4 * index - const int kElementsStartOffset = - NameDictionary::kHeaderSize + - NameDictionary::kElementsStartIndex * kPointerSize; - const int kDetailsOffset = kElementsStartOffset + 2 * kPointerSize; - int kTypeAndReadOnlyMask = - PropertyDetails::TypeField::kMask | - PropertyDetails::AttributesField::encode(READ_ONLY); - __ LoadP(scratch1, FieldMemOperand(scratch2, kDetailsOffset)); - __ LoadRR(r0, scratch2); - __ LoadSmiLiteral(scratch2, Smi::FromInt(kTypeAndReadOnlyMask)); - __ AndP(scratch2, scratch1); - __ bne(miss /*, cr0*/); - __ LoadRR(scratch2, r0); - - // Store the value at the masked, scaled index and return. - const int kValueOffset = kElementsStartOffset + kPointerSize; - __ AddP(scratch2, Operand(kValueOffset - kHeapObjectTag)); - __ StoreP(value, MemOperand(scratch2)); - - // Update the write barrier. Make sure not to clobber the value. - __ LoadRR(scratch1, value); - __ RecordWrite(elements, scratch2, scratch1, kLRHasNotBeenSaved, - kDontSaveFPRegs); -} - -void LoadIC::GenerateNormal(MacroAssembler* masm) { - Register dictionary = r2; - DCHECK(!dictionary.is(LoadDescriptor::ReceiverRegister())); - DCHECK(!dictionary.is(LoadDescriptor::NameRegister())); - - Label slow; - - __ LoadP(dictionary, FieldMemOperand(LoadDescriptor::ReceiverRegister(), - JSObject::kPropertiesOffset)); - GenerateDictionaryLoad(masm, &slow, dictionary, - LoadDescriptor::NameRegister(), r2, r5, r6); - __ Ret(); - - // Dictionary load failed, go slow (but don't miss). - __ bind(&slow); - GenerateRuntimeGetProperty(masm); -} - -// A register that isn't one of the parameters to the load ic. -static const Register LoadIC_TempRegister() { return r5; } - -void LoadIC::GenerateRuntimeGetProperty(MacroAssembler* masm) { - // The return address is in lr. - - __ LoadRR(LoadIC_TempRegister(), LoadDescriptor::ReceiverRegister()); - __ Push(LoadIC_TempRegister(), LoadDescriptor::NameRegister()); - - // Do tail-call to runtime routine. - __ TailCallRuntime(Runtime::kGetProperty); -} - static void StoreIC_PushArgs(MacroAssembler* masm) { __ Push(StoreWithVectorDescriptor::ValueRegister(), StoreWithVectorDescriptor::SlotRegister(), @@ -170,37 +40,6 @@ void KeyedStoreIC::GenerateSlow(MacroAssembler* masm) { __ TailCallRuntime(Runtime::kKeyedStoreIC_Slow); } -void StoreIC::GenerateMiss(MacroAssembler* masm) { - StoreIC_PushArgs(masm); - - // Perform tail call to the entry. - __ TailCallRuntime(Runtime::kStoreIC_Miss); -} - -void StoreIC::GenerateNormal(MacroAssembler* masm) { - Label miss; - Register receiver = StoreDescriptor::ReceiverRegister(); - Register name = StoreDescriptor::NameRegister(); - Register value = StoreDescriptor::ValueRegister(); - Register dictionary = r7; - DCHECK(receiver.is(r3)); - DCHECK(name.is(r4)); - DCHECK(value.is(r2)); - DCHECK(StoreWithVectorDescriptor::VectorRegister().is(r5)); - DCHECK(StoreWithVectorDescriptor::SlotRegister().is(r6)); - - __ LoadP(dictionary, FieldMemOperand(receiver, JSObject::kPropertiesOffset)); - - GenerateDictionaryStore(masm, &miss, dictionary, name, value, r8, r9); - Counters* counters = masm->isolate()->counters(); - __ IncrementCounter(counters->ic_store_normal_hit(), 1, r8, r9); - __ Ret(); - - __ bind(&miss); - __ IncrementCounter(counters->ic_store_normal_miss(), 1, r8, r9); - GenerateMiss(masm); -} - #undef __ Condition CompareIC::ComputeCondition(Token::Value op) { diff --git a/src/ic/x64/ic-x64.cc b/src/ic/x64/ic-x64.cc index de8782510d..587ebd3daa 100644 --- a/src/ic/x64/ic-x64.cc +++ b/src/ic/x64/ic-x64.cc @@ -18,143 +18,6 @@ namespace internal { #define __ ACCESS_MASM(masm) -// Helper function used to load a property from a dictionary backing storage. -// This function may return false negatives, so miss_label -// must always call a backup property load that is complete. -// This function is safe to call if name is not an internalized string, -// and will jump to the miss_label in that case. -// The generated code assumes that the receiver has slow properties, -// is not a global object and does not have interceptors. -static void GenerateDictionaryLoad(MacroAssembler* masm, Label* miss_label, - Register elements, Register name, - Register r0, Register r1, Register result) { - // Register use: - // - // elements - holds the property dictionary on entry and is unchanged. - // - // name - holds the name of the property on entry and is unchanged. - // - // r0 - used to hold the capacity of the property dictionary. - // - // r1 - used to hold the index into the property dictionary. - // - // result - holds the result on exit if the load succeeded. - - Label done; - - // Probe the dictionary. - NameDictionaryLookupStub::GeneratePositiveLookup(masm, miss_label, &done, - elements, name, r0, r1); - - // If probing finds an entry in the dictionary, r1 contains the - // index into the dictionary. Check that the value is a normal - // property. - __ bind(&done); - const int kElementsStartOffset = - NameDictionary::kHeaderSize + - NameDictionary::kElementsStartIndex * kPointerSize; - const int kDetailsOffset = kElementsStartOffset + 2 * kPointerSize; - __ Test(Operand(elements, r1, times_pointer_size, - kDetailsOffset - kHeapObjectTag), - Smi::FromInt(PropertyDetails::TypeField::kMask)); - __ j(not_zero, miss_label); - - // Get the value at the masked, scaled index. - const int kValueOffset = kElementsStartOffset + kPointerSize; - __ movp(result, Operand(elements, r1, times_pointer_size, - kValueOffset - kHeapObjectTag)); -} - - -// Helper function used to store a property to a dictionary backing -// storage. This function may fail to store a property even though it -// is in the dictionary, so code at miss_label must always call a -// backup property store that is complete. This function is safe to -// call if name is not an internalized string, and will jump to the miss_label -// in that case. The generated code assumes that the receiver has slow -// properties, is not a global object and does not have interceptors. -static void GenerateDictionaryStore(MacroAssembler* masm, Label* miss_label, - Register elements, Register name, - Register value, Register scratch0, - Register scratch1) { - // Register use: - // - // elements - holds the property dictionary on entry and is clobbered. - // - // name - holds the name of the property on entry and is unchanged. - // - // value - holds the value to store and is unchanged. - // - // scratch0 - used during the positive dictionary lookup and is clobbered. - // - // scratch1 - used for index into the property dictionary and is clobbered. - Label done; - - // Probe the dictionary. - NameDictionaryLookupStub::GeneratePositiveLookup( - masm, miss_label, &done, elements, name, scratch0, scratch1); - - // If probing finds an entry in the dictionary, scratch0 contains the - // index into the dictionary. Check that the value is a normal - // property that is not read only. - __ bind(&done); - const int kElementsStartOffset = - NameDictionary::kHeaderSize + - NameDictionary::kElementsStartIndex * kPointerSize; - const int kDetailsOffset = kElementsStartOffset + 2 * kPointerSize; - const int kTypeAndReadOnlyMask = - PropertyDetails::TypeField::kMask | - PropertyDetails::AttributesField::encode(READ_ONLY); - __ Test(Operand(elements, scratch1, times_pointer_size, - kDetailsOffset - kHeapObjectTag), - Smi::FromInt(kTypeAndReadOnlyMask)); - __ j(not_zero, miss_label); - - // Store the value at the masked, scaled index. - const int kValueOffset = kElementsStartOffset + kPointerSize; - __ leap(scratch1, Operand(elements, scratch1, times_pointer_size, - kValueOffset - kHeapObjectTag)); - __ movp(Operand(scratch1, 0), value); - - // Update write barrier. Make sure not to clobber the value. - __ movp(scratch0, value); - __ RecordWrite(elements, scratch1, scratch0, kDontSaveFPRegs); -} - -void LoadIC::GenerateNormal(MacroAssembler* masm) { - Register dictionary = rax; - DCHECK(!dictionary.is(LoadDescriptor::ReceiverRegister())); - DCHECK(!dictionary.is(LoadDescriptor::NameRegister())); - - Label slow; - - __ movp(dictionary, FieldOperand(LoadDescriptor::ReceiverRegister(), - JSObject::kPropertiesOffset)); - GenerateDictionaryLoad(masm, &slow, dictionary, - LoadDescriptor::NameRegister(), rbx, rdi, rax); - __ ret(0); - - // Dictionary load failed, go slow (but don't miss). - __ bind(&slow); - LoadIC::GenerateRuntimeGetProperty(masm); -} - -void LoadIC::GenerateRuntimeGetProperty(MacroAssembler* masm) { - // The return address is on the stack. - Register receiver = LoadDescriptor::ReceiverRegister(); - Register name = LoadDescriptor::NameRegister(); - - DCHECK(!rbx.is(receiver) && !rbx.is(name)); - - __ PopReturnAddressTo(rbx); - __ Push(receiver); - __ Push(name); - __ PushReturnAddressFrom(rbx); - - // Do tail-call to runtime routine. - __ TailCallRuntime(Runtime::kGetProperty); -} - static void StoreIC_PushArgs(MacroAssembler* masm) { Register receiver = StoreWithVectorDescriptor::ReceiverRegister(); Register name = StoreWithVectorDescriptor::NameRegister(); @@ -173,38 +36,6 @@ static void StoreIC_PushArgs(MacroAssembler* masm) { __ PushReturnAddressFrom(temp); } - -void StoreIC::GenerateMiss(MacroAssembler* masm) { - // Return address is on the stack. - StoreIC_PushArgs(masm); - - // Perform tail call to the entry. - __ TailCallRuntime(Runtime::kStoreIC_Miss); -} - - -void StoreIC::GenerateNormal(MacroAssembler* masm) { - Register receiver = StoreDescriptor::ReceiverRegister(); - Register name = StoreDescriptor::NameRegister(); - Register value = StoreDescriptor::ValueRegister(); - Register dictionary = r11; - DCHECK(!AreAliased(dictionary, StoreWithVectorDescriptor::VectorRegister(), - StoreWithVectorDescriptor::SlotRegister())); - - Label miss; - - __ movp(dictionary, FieldOperand(receiver, JSObject::kPropertiesOffset)); - GenerateDictionaryStore(masm, &miss, dictionary, name, value, r8, r9); - Counters* counters = masm->isolate()->counters(); - __ IncrementCounter(counters->ic_store_normal_hit(), 1); - __ ret(0); - - __ bind(&miss); - __ IncrementCounter(counters->ic_store_normal_miss(), 1); - GenerateMiss(masm); -} - - void KeyedStoreIC::GenerateMiss(MacroAssembler* masm) { // Return address is on the stack. StoreIC_PushArgs(masm); diff --git a/src/ic/x87/ic-x87.cc b/src/ic/x87/ic-x87.cc index 7953b07eb3..049a85e92e 100644 --- a/src/ic/x87/ic-x87.cc +++ b/src/ic/x87/ic-x87.cc @@ -18,141 +18,6 @@ namespace internal { #define __ ACCESS_MASM(masm) -// Helper function used to load a property from a dictionary backing -// storage. This function may fail to load a property even though it is -// in the dictionary, so code at miss_label must always call a backup -// property load that is complete. This function is safe to call if -// name is not internalized, and will jump to the miss_label in that -// case. The generated code assumes that the receiver has slow -// properties, is not a global object and does not have interceptors. -static void GenerateDictionaryLoad(MacroAssembler* masm, Label* miss_label, - Register elements, Register name, - Register r0, Register r1, Register result) { - // Register use: - // - // elements - holds the property dictionary on entry and is unchanged. - // - // name - holds the name of the property on entry and is unchanged. - // - // Scratch registers: - // - // r0 - used for the index into the property dictionary - // - // r1 - used to hold the capacity of the property dictionary. - // - // result - holds the result on exit. - - Label done; - - // Probe the dictionary. - NameDictionaryLookupStub::GeneratePositiveLookup(masm, miss_label, &done, - elements, name, r0, r1); - - // If probing finds an entry in the dictionary, r0 contains the - // index into the dictionary. Check that the value is a normal - // property. - __ bind(&done); - const int kElementsStartOffset = - NameDictionary::kHeaderSize + - NameDictionary::kElementsStartIndex * kPointerSize; - const int kDetailsOffset = kElementsStartOffset + 2 * kPointerSize; - __ test(Operand(elements, r0, times_4, kDetailsOffset - kHeapObjectTag), - Immediate(PropertyDetails::TypeField::kMask << kSmiTagSize)); - __ j(not_zero, miss_label); - - // Get the value at the masked, scaled index. - const int kValueOffset = kElementsStartOffset + kPointerSize; - __ mov(result, Operand(elements, r0, times_4, kValueOffset - kHeapObjectTag)); -} - - -// Helper function used to store a property to a dictionary backing -// storage. This function may fail to store a property eventhough it -// is in the dictionary, so code at miss_label must always call a -// backup property store that is complete. This function is safe to -// call if name is not internalized, and will jump to the miss_label in -// that case. The generated code assumes that the receiver has slow -// properties, is not a global object and does not have interceptors. -static void GenerateDictionaryStore(MacroAssembler* masm, Label* miss_label, - Register elements, Register name, - Register value, Register r0, Register r1) { - // Register use: - // - // elements - holds the property dictionary on entry and is clobbered. - // - // name - holds the name of the property on entry and is unchanged. - // - // value - holds the value to store and is unchanged. - // - // r0 - used for index into the property dictionary and is clobbered. - // - // r1 - used to hold the capacity of the property dictionary and is clobbered. - Label done; - - - // Probe the dictionary. - NameDictionaryLookupStub::GeneratePositiveLookup(masm, miss_label, &done, - elements, name, r0, r1); - - // If probing finds an entry in the dictionary, r0 contains the - // index into the dictionary. Check that the value is a normal - // property that is not read only. - __ bind(&done); - const int kElementsStartOffset = - NameDictionary::kHeaderSize + - NameDictionary::kElementsStartIndex * kPointerSize; - const int kDetailsOffset = kElementsStartOffset + 2 * kPointerSize; - const int kTypeAndReadOnlyMask = - (PropertyDetails::TypeField::kMask | - PropertyDetails::AttributesField::encode(READ_ONLY)) - << kSmiTagSize; - __ test(Operand(elements, r0, times_4, kDetailsOffset - kHeapObjectTag), - Immediate(kTypeAndReadOnlyMask)); - __ j(not_zero, miss_label); - - // Store the value at the masked, scaled index. - const int kValueOffset = kElementsStartOffset + kPointerSize; - __ lea(r0, Operand(elements, r0, times_4, kValueOffset - kHeapObjectTag)); - __ mov(Operand(r0, 0), value); - - // Update write barrier. Make sure not to clobber the value. - __ mov(r1, value); - __ RecordWrite(elements, r0, r1, kDontSaveFPRegs); -} - -void LoadIC::GenerateNormal(MacroAssembler* masm) { - Register dictionary = eax; - DCHECK(!dictionary.is(LoadDescriptor::ReceiverRegister())); - DCHECK(!dictionary.is(LoadDescriptor::NameRegister())); - - Label slow; - - __ mov(dictionary, FieldOperand(LoadDescriptor::ReceiverRegister(), - JSObject::kPropertiesOffset)); - GenerateDictionaryLoad(masm, &slow, dictionary, - LoadDescriptor::NameRegister(), edi, ebx, eax); - __ ret(0); - - // Dictionary load failed, go slow (but don't miss). - __ bind(&slow); - GenerateRuntimeGetProperty(masm); -} - -void LoadIC::GenerateRuntimeGetProperty(MacroAssembler* masm) { - // Return address is on the stack. - Register receiver = LoadDescriptor::ReceiverRegister(); - Register name = LoadDescriptor::NameRegister(); - DCHECK(!ebx.is(receiver) && !ebx.is(name)); - - __ pop(ebx); - __ push(receiver); - __ push(name); - __ push(ebx); - - // Do tail-call to runtime routine. - __ TailCallRuntime(Runtime::kGetProperty); -} - static void StoreIC_PushArgs(MacroAssembler* masm) { Register receiver = StoreWithVectorDescriptor::ReceiverRegister(); Register name = StoreWithVectorDescriptor::NameRegister(); @@ -171,50 +36,6 @@ static void StoreIC_PushArgs(MacroAssembler* masm) { __ push(return_address); } - -void StoreIC::GenerateMiss(MacroAssembler* masm) { - // Return address is on the stack. - StoreIC_PushArgs(masm); - - // Perform tail call to the entry. - __ TailCallRuntime(Runtime::kStoreIC_Miss); -} - - -void StoreIC::GenerateNormal(MacroAssembler* masm) { - typedef StoreWithVectorDescriptor Descriptor; - Label restore_miss; - Register receiver = Descriptor::ReceiverRegister(); - Register name = Descriptor::NameRegister(); - Register value = Descriptor::ValueRegister(); - // Since the slot and vector values are passed on the stack we can use - // respective registers as scratch registers. - Register scratch1 = Descriptor::VectorRegister(); - Register scratch2 = Descriptor::SlotRegister(); - - __ LoadParameterFromStack(value, Descriptor::kValue); - - // A lot of registers are needed for storing to slow case objects. - // Push and restore receiver but rely on GenerateDictionaryStore preserving - // the value and name. - __ push(receiver); - - Register dictionary = receiver; - __ mov(dictionary, FieldOperand(receiver, JSObject::kPropertiesOffset)); - GenerateDictionaryStore(masm, &restore_miss, dictionary, name, value, - scratch1, scratch2); - __ Drop(1); - Counters* counters = masm->isolate()->counters(); - __ IncrementCounter(counters->ic_store_normal_hit(), 1); - __ ret(Descriptor::kStackArgumentsCount * kPointerSize); - - __ bind(&restore_miss); - __ pop(receiver); - __ IncrementCounter(counters->ic_store_normal_miss(), 1); - GenerateMiss(masm); -} - - void KeyedStoreIC::GenerateMiss(MacroAssembler* masm) { // Return address is on the stack. StoreIC_PushArgs(masm); diff --git a/src/mips/code-stubs-mips.cc b/src/mips/code-stubs-mips.cc index 741dd3e3c9..df5da8fa5f 100644 --- a/src/mips/code-stubs-mips.cc +++ b/src/mips/code-stubs-mips.cc @@ -2843,85 +2843,6 @@ void NameDictionaryLookupStub::GenerateNegativeLookup(MacroAssembler* masm, __ Branch(miss, ne, at, Operand(zero_reg)); } - -// Probe the name dictionary in the |elements| register. Jump to the -// |done| label if a property with the given name is found. Jump to -// the |miss| label otherwise. -// If lookup was successful |scratch2| will be equal to elements + 4 * index. -void NameDictionaryLookupStub::GeneratePositiveLookup(MacroAssembler* masm, - Label* miss, - Label* done, - Register elements, - Register name, - Register scratch1, - Register scratch2) { - DCHECK(!elements.is(scratch1)); - DCHECK(!elements.is(scratch2)); - DCHECK(!name.is(scratch1)); - DCHECK(!name.is(scratch2)); - - __ AssertName(name); - - // Compute the capacity mask. - __ lw(scratch1, FieldMemOperand(elements, kCapacityOffset)); - __ sra(scratch1, scratch1, kSmiTagSize); // convert smi to int - __ Subu(scratch1, scratch1, Operand(1)); - - // Generate an unrolled loop that performs a few probes before - // giving up. Measurements done on Gmail indicate that 2 probes - // cover ~93% of loads from dictionaries. - for (int i = 0; i < kInlinedProbes; i++) { - // Compute the masked index: (hash + i + i * i) & mask. - __ lw(scratch2, FieldMemOperand(name, Name::kHashFieldOffset)); - if (i > 0) { - // Add the probe offset (i + i * i) left shifted to avoid right shifting - // the hash in a separate instruction. The value hash + i + i * i is right - // shifted in the following and instruction. - DCHECK(NameDictionary::GetProbeOffset(i) < - 1 << (32 - Name::kHashFieldOffset)); - __ Addu(scratch2, scratch2, Operand( - NameDictionary::GetProbeOffset(i) << Name::kHashShift)); - } - __ srl(scratch2, scratch2, Name::kHashShift); - __ And(scratch2, scratch1, scratch2); - - // Scale the index by multiplying by the element size. - STATIC_ASSERT(NameDictionary::kEntrySize == 3); - // scratch2 = scratch2 * 3. - - __ Lsa(scratch2, scratch2, scratch2, 1); - - // Check if the key is identical to the name. - __ Lsa(scratch2, elements, scratch2, 2); - __ lw(at, FieldMemOperand(scratch2, kElementsStartOffset)); - __ Branch(done, eq, name, Operand(at)); - } - - const int spill_mask = - (ra.bit() | t2.bit() | t1.bit() | t0.bit() | - a3.bit() | a2.bit() | a1.bit() | a0.bit() | v0.bit()) & - ~(scratch1.bit() | scratch2.bit()); - - __ MultiPush(spill_mask); - if (name.is(a0)) { - DCHECK(!elements.is(a1)); - __ Move(a1, name); - __ Move(a0, elements); - } else { - __ Move(a0, elements); - __ Move(a1, name); - } - NameDictionaryLookupStub stub(masm->isolate(), POSITIVE_LOOKUP); - __ CallStub(&stub); - __ mov(scratch2, a2); - __ mov(at, v0); - __ MultiPop(spill_mask); - - __ Branch(done, ne, at, Operand(zero_reg)); - __ Branch(miss, eq, at, Operand(zero_reg)); -} - - void NameDictionaryLookupStub::Generate(MacroAssembler* masm) { // This stub overrides SometimesSetsUpAFrame() to return false. That means // we cannot call anything that could cause a GC from this stub. diff --git a/src/mips/code-stubs-mips.h b/src/mips/code-stubs-mips.h index 8d7d70a6a8..e2dd4a9b28 100644 --- a/src/mips/code-stubs-mips.h +++ b/src/mips/code-stubs-mips.h @@ -300,14 +300,6 @@ class NameDictionaryLookupStub: public PlatformCodeStub { Handle name, Register scratch0); - static void GeneratePositiveLookup(MacroAssembler* masm, - Label* miss, - Label* done, - Register elements, - Register name, - Register r0, - Register r1); - bool SometimesSetsUpAFrame() override { return false; } private: diff --git a/src/mips64/code-stubs-mips64.cc b/src/mips64/code-stubs-mips64.cc index ad67d5f2c1..9e56dfd1bd 100644 --- a/src/mips64/code-stubs-mips64.cc +++ b/src/mips64/code-stubs-mips64.cc @@ -2847,84 +2847,6 @@ void NameDictionaryLookupStub::GenerateNegativeLookup(MacroAssembler* masm, __ Branch(miss, ne, at, Operand(zero_reg)); } - -// Probe the name dictionary in the |elements| register. Jump to the -// |done| label if a property with the given name is found. Jump to -// the |miss| label otherwise. -// If lookup was successful |scratch2| will be equal to elements + 4 * index. -void NameDictionaryLookupStub::GeneratePositiveLookup(MacroAssembler* masm, - Label* miss, - Label* done, - Register elements, - Register name, - Register scratch1, - Register scratch2) { - DCHECK(!elements.is(scratch1)); - DCHECK(!elements.is(scratch2)); - DCHECK(!name.is(scratch1)); - DCHECK(!name.is(scratch2)); - - __ AssertName(name); - - // Compute the capacity mask. - __ ld(scratch1, FieldMemOperand(elements, kCapacityOffset)); - __ SmiUntag(scratch1); - __ Dsubu(scratch1, scratch1, Operand(1)); - - // Generate an unrolled loop that performs a few probes before - // giving up. Measurements done on Gmail indicate that 2 probes - // cover ~93% of loads from dictionaries. - for (int i = 0; i < kInlinedProbes; i++) { - // Compute the masked index: (hash + i + i * i) & mask. - __ lwu(scratch2, FieldMemOperand(name, Name::kHashFieldOffset)); - if (i > 0) { - // Add the probe offset (i + i * i) left shifted to avoid right shifting - // the hash in a separate instruction. The value hash + i + i * i is right - // shifted in the following and instruction. - DCHECK(NameDictionary::GetProbeOffset(i) < - 1 << (32 - Name::kHashFieldOffset)); - __ Daddu(scratch2, scratch2, Operand( - NameDictionary::GetProbeOffset(i) << Name::kHashShift)); - } - __ dsrl(scratch2, scratch2, Name::kHashShift); - __ And(scratch2, scratch1, scratch2); - - // Scale the index by multiplying by the entry size. - STATIC_ASSERT(NameDictionary::kEntrySize == 3); - // scratch2 = scratch2 * 3. - __ Dlsa(scratch2, scratch2, scratch2, 1); - - // Check if the key is identical to the name. - __ Dlsa(scratch2, elements, scratch2, kPointerSizeLog2); - __ ld(at, FieldMemOperand(scratch2, kElementsStartOffset)); - __ Branch(done, eq, name, Operand(at)); - } - - const int spill_mask = - (ra.bit() | a6.bit() | a5.bit() | a4.bit() | - a3.bit() | a2.bit() | a1.bit() | a0.bit() | v0.bit()) & - ~(scratch1.bit() | scratch2.bit()); - - __ MultiPush(spill_mask); - if (name.is(a0)) { - DCHECK(!elements.is(a1)); - __ Move(a1, name); - __ Move(a0, elements); - } else { - __ Move(a0, elements); - __ Move(a1, name); - } - NameDictionaryLookupStub stub(masm->isolate(), POSITIVE_LOOKUP); - __ CallStub(&stub); - __ mov(scratch2, a2); - __ mov(at, v0); - __ MultiPop(spill_mask); - - __ Branch(done, ne, at, Operand(zero_reg)); - __ Branch(miss, eq, at, Operand(zero_reg)); -} - - void NameDictionaryLookupStub::Generate(MacroAssembler* masm) { // This stub overrides SometimesSetsUpAFrame() to return false. That means // we cannot call anything that could cause a GC from this stub. diff --git a/src/mips64/code-stubs-mips64.h b/src/mips64/code-stubs-mips64.h index b619bf9c14..42f90ad886 100644 --- a/src/mips64/code-stubs-mips64.h +++ b/src/mips64/code-stubs-mips64.h @@ -301,14 +301,6 @@ class NameDictionaryLookupStub: public PlatformCodeStub { Handle name, Register scratch0); - static void GeneratePositiveLookup(MacroAssembler* masm, - Label* miss, - Label* done, - Register elements, - Register name, - Register r0, - Register r1); - bool SometimesSetsUpAFrame() override { return false; } private: diff --git a/src/ppc/code-stubs-ppc.cc b/src/ppc/code-stubs-ppc.cc index 8e6f3817c5..1f52733109 100644 --- a/src/ppc/code-stubs-ppc.cc +++ b/src/ppc/code-stubs-ppc.cc @@ -2803,84 +2803,6 @@ void NameDictionaryLookupStub::GenerateNegativeLookup( __ bne(miss); } - -// Probe the name dictionary in the |elements| register. Jump to the -// |done| label if a property with the given name is found. Jump to -// the |miss| label otherwise. -// If lookup was successful |scratch2| will be equal to elements + 4 * index. -void NameDictionaryLookupStub::GeneratePositiveLookup( - MacroAssembler* masm, Label* miss, Label* done, Register elements, - Register name, Register scratch1, Register scratch2) { - DCHECK(!elements.is(scratch1)); - DCHECK(!elements.is(scratch2)); - DCHECK(!name.is(scratch1)); - DCHECK(!name.is(scratch2)); - - __ AssertName(name); - - // Compute the capacity mask. - __ LoadP(scratch1, FieldMemOperand(elements, kCapacityOffset)); - __ SmiUntag(scratch1); // convert smi to int - __ subi(scratch1, scratch1, Operand(1)); - - // Generate an unrolled loop that performs a few probes before - // giving up. Measurements done on Gmail indicate that 2 probes - // cover ~93% of loads from dictionaries. - for (int i = 0; i < kInlinedProbes; i++) { - // Compute the masked index: (hash + i + i * i) & mask. - __ lwz(scratch2, FieldMemOperand(name, Name::kHashFieldOffset)); - if (i > 0) { - // Add the probe offset (i + i * i) left shifted to avoid right shifting - // the hash in a separate instruction. The value hash + i + i * i is right - // shifted in the following and instruction. - DCHECK(NameDictionary::GetProbeOffset(i) < - 1 << (32 - Name::kHashFieldOffset)); - __ addi(scratch2, scratch2, - Operand(NameDictionary::GetProbeOffset(i) << Name::kHashShift)); - } - __ srwi(scratch2, scratch2, Operand(Name::kHashShift)); - __ and_(scratch2, scratch1, scratch2); - - // Scale the index by multiplying by the entry size. - STATIC_ASSERT(NameDictionary::kEntrySize == 3); - // scratch2 = scratch2 * 3. - __ ShiftLeftImm(ip, scratch2, Operand(1)); - __ add(scratch2, scratch2, ip); - - // Check if the key is identical to the name. - __ ShiftLeftImm(ip, scratch2, Operand(kPointerSizeLog2)); - __ add(scratch2, elements, ip); - __ LoadP(ip, FieldMemOperand(scratch2, kElementsStartOffset)); - __ cmp(name, ip); - __ beq(done); - } - - const int spill_mask = (r0.bit() | r9.bit() | r8.bit() | r7.bit() | r6.bit() | - r5.bit() | r4.bit() | r3.bit()) & - ~(scratch1.bit() | scratch2.bit()); - - __ mflr(r0); - __ MultiPush(spill_mask); - if (name.is(r3)) { - DCHECK(!elements.is(r4)); - __ mr(r4, name); - __ mr(r3, elements); - } else { - __ mr(r3, elements); - __ mr(r4, name); - } - NameDictionaryLookupStub stub(masm->isolate(), POSITIVE_LOOKUP); - __ CallStub(&stub); - __ cmpi(r3, Operand::Zero()); - __ mr(scratch2, r5); - __ MultiPop(spill_mask); - __ mtlr(r0); - - __ bne(done); - __ beq(miss); -} - - void NameDictionaryLookupStub::Generate(MacroAssembler* masm) { // This stub overrides SometimesSetsUpAFrame() to return false. That means // we cannot call anything that could cause a GC from this stub. diff --git a/src/ppc/code-stubs-ppc.h b/src/ppc/code-stubs-ppc.h index 56ba0e545b..f873f93679 100644 --- a/src/ppc/code-stubs-ppc.h +++ b/src/ppc/code-stubs-ppc.h @@ -288,10 +288,6 @@ class NameDictionaryLookupStub : public PlatformCodeStub { Register properties, Handle name, Register scratch0); - static void GeneratePositiveLookup(MacroAssembler* masm, Label* miss, - Label* done, Register elements, - Register name, Register r0, Register r1); - bool SometimesSetsUpAFrame() override { return false; } private: diff --git a/src/s390/code-stubs-s390.cc b/src/s390/code-stubs-s390.cc index f12308a43a..8016b327e2 100644 --- a/src/s390/code-stubs-s390.cc +++ b/src/s390/code-stubs-s390.cc @@ -2754,83 +2754,6 @@ void NameDictionaryLookupStub::GenerateNegativeLookup( __ bne(miss); } -// Probe the name dictionary in the |elements| register. Jump to the -// |done| label if a property with the given name is found. Jump to -// the |miss| label otherwise. -// If lookup was successful |scratch2| will be equal to elements + 4 * index. -void NameDictionaryLookupStub::GeneratePositiveLookup( - MacroAssembler* masm, Label* miss, Label* done, Register elements, - Register name, Register scratch1, Register scratch2) { - DCHECK(!elements.is(scratch1)); - DCHECK(!elements.is(scratch2)); - DCHECK(!name.is(scratch1)); - DCHECK(!name.is(scratch2)); - - __ AssertName(name); - - // Compute the capacity mask. - __ LoadP(scratch1, FieldMemOperand(elements, kCapacityOffset)); - __ SmiUntag(scratch1); // convert smi to int - __ SubP(scratch1, Operand(1)); - - // Generate an unrolled loop that performs a few probes before - // giving up. Measurements done on Gmail indicate that 2 probes - // cover ~93% of loads from dictionaries. - for (int i = 0; i < kInlinedProbes; i++) { - // Compute the masked index: (hash + i + i * i) & mask. - __ LoadlW(scratch2, FieldMemOperand(name, String::kHashFieldOffset)); - if (i > 0) { - // Add the probe offset (i + i * i) left shifted to avoid right shifting - // the hash in a separate instruction. The value hash + i + i * i is right - // shifted in the following and instruction. - DCHECK(NameDictionary::GetProbeOffset(i) < - 1 << (32 - Name::kHashFieldOffset)); - __ AddP(scratch2, - Operand(NameDictionary::GetProbeOffset(i) << Name::kHashShift)); - } - __ srl(scratch2, Operand(String::kHashShift)); - __ AndP(scratch2, scratch1); - - // Scale the index by multiplying by the entry size. - STATIC_ASSERT(NameDictionary::kEntrySize == 3); - // scratch2 = scratch2 * 3. - __ ShiftLeftP(ip, scratch2, Operand(1)); - __ AddP(scratch2, ip); - - // Check if the key is identical to the name. - __ ShiftLeftP(ip, scratch2, Operand(kPointerSizeLog2)); - __ AddP(scratch2, elements, ip); - __ LoadP(ip, FieldMemOperand(scratch2, kElementsStartOffset)); - __ CmpP(name, ip); - __ beq(done); - } - - const int spill_mask = (r0.bit() | r8.bit() | r7.bit() | r6.bit() | r5.bit() | - r4.bit() | r3.bit() | r2.bit()) & - ~(scratch1.bit() | scratch2.bit()); - - __ LoadRR(r0, r14); - __ MultiPush(spill_mask); - if (name.is(r2)) { - DCHECK(!elements.is(r3)); - __ LoadRR(r3, name); - __ LoadRR(r2, elements); - } else { - __ LoadRR(r2, elements); - __ LoadRR(r3, name); - } - NameDictionaryLookupStub stub(masm->isolate(), POSITIVE_LOOKUP); - __ CallStub(&stub); - __ LoadRR(r1, r2); - __ LoadRR(scratch2, r4); - __ MultiPop(spill_mask); - __ LoadRR(r14, r0); - - __ CmpP(r1, Operand::Zero()); - __ bne(done); - __ beq(miss); -} - void NameDictionaryLookupStub::Generate(MacroAssembler* masm) { // This stub overrides SometimesSetsUpAFrame() to return false. That means // we cannot call anything that could cause a GC from this stub. diff --git a/src/s390/code-stubs-s390.h b/src/s390/code-stubs-s390.h index f43dd3a0da..c599308792 100644 --- a/src/s390/code-stubs-s390.h +++ b/src/s390/code-stubs-s390.h @@ -312,10 +312,6 @@ class NameDictionaryLookupStub : public PlatformCodeStub { Register properties, Handle name, Register scratch0); - static void GeneratePositiveLookup(MacroAssembler* masm, Label* miss, - Label* done, Register elements, - Register name, Register r0, Register r1); - bool SometimesSetsUpAFrame() override { return false; } private: diff --git a/src/x64/code-stubs-x64.cc b/src/x64/code-stubs-x64.cc index a0b77c2aa2..88810e93c6 100644 --- a/src/x64/code-stubs-x64.cc +++ b/src/x64/code-stubs-x64.cc @@ -2584,61 +2584,6 @@ void NameDictionaryLookupStub::GenerateNegativeLookup(MacroAssembler* masm, __ jmp(done); } - -// Probe the name dictionary in the |elements| register. Jump to the -// |done| label if a property with the given name is found leaving the -// index into the dictionary in |r1|. Jump to the |miss| label -// otherwise. -void NameDictionaryLookupStub::GeneratePositiveLookup(MacroAssembler* masm, - Label* miss, - Label* done, - Register elements, - Register name, - Register r0, - Register r1) { - DCHECK(!elements.is(r0)); - DCHECK(!elements.is(r1)); - DCHECK(!name.is(r0)); - DCHECK(!name.is(r1)); - - __ AssertName(name); - - __ SmiToInteger32(r0, FieldOperand(elements, kCapacityOffset)); - __ decl(r0); - - for (int i = 0; i < kInlinedProbes; i++) { - // Compute the masked index: (hash + i + i * i) & mask. - __ movl(r1, FieldOperand(name, Name::kHashFieldOffset)); - __ shrl(r1, Immediate(Name::kHashShift)); - if (i > 0) { - __ addl(r1, Immediate(NameDictionary::GetProbeOffset(i))); - } - __ andp(r1, r0); - - // Scale the index by multiplying by the entry size. - STATIC_ASSERT(NameDictionary::kEntrySize == 3); - __ leap(r1, Operand(r1, r1, times_2, 0)); // r1 = r1 * 3 - - // Check if the key is identical to the name. - __ cmpp(name, Operand(elements, r1, times_pointer_size, - kElementsStartOffset - kHeapObjectTag)); - __ j(equal, done); - } - - NameDictionaryLookupStub stub(masm->isolate(), elements, r0, r1, - POSITIVE_LOOKUP); - __ Push(name); - __ movl(r0, FieldOperand(name, Name::kHashFieldOffset)); - __ shrl(r0, Immediate(Name::kHashShift)); - __ Push(r0); - __ CallStub(&stub); - - __ testp(r0, r0); - __ j(zero, miss); - __ jmp(done); -} - - void NameDictionaryLookupStub::Generate(MacroAssembler* masm) { // This stub overrides SometimesSetsUpAFrame() to return false. That means // we cannot call anything that could cause a GC from this stub. diff --git a/src/x64/code-stubs-x64.h b/src/x64/code-stubs-x64.h index 9c19c02f45..bf503dfc6b 100644 --- a/src/x64/code-stubs-x64.h +++ b/src/x64/code-stubs-x64.h @@ -54,14 +54,6 @@ class NameDictionaryLookupStub: public PlatformCodeStub { Handle name, Register r0); - static void GeneratePositiveLookup(MacroAssembler* masm, - Label* miss, - Label* done, - Register elements, - Register name, - Register r0, - Register r1); - bool SometimesSetsUpAFrame() override { return false; } private: diff --git a/src/x87/code-stubs-x87.cc b/src/x87/code-stubs-x87.cc index 4d161d4fed..01b2b5b70f 100644 --- a/src/x87/code-stubs-x87.cc +++ b/src/x87/code-stubs-x87.cc @@ -2462,67 +2462,6 @@ void NameDictionaryLookupStub::GenerateNegativeLookup(MacroAssembler* masm, __ jmp(done); } - -// Probe the name dictionary in the |elements| register. Jump to the -// |done| label if a property with the given name is found leaving the -// index into the dictionary in |r0|. Jump to the |miss| label -// otherwise. -void NameDictionaryLookupStub::GeneratePositiveLookup(MacroAssembler* masm, - Label* miss, - Label* done, - Register elements, - Register name, - Register r0, - Register r1) { - DCHECK(!elements.is(r0)); - DCHECK(!elements.is(r1)); - DCHECK(!name.is(r0)); - DCHECK(!name.is(r1)); - - __ AssertName(name); - - __ mov(r1, FieldOperand(elements, kCapacityOffset)); - __ shr(r1, kSmiTagSize); // convert smi to int - __ dec(r1); - - // Generate an unrolled loop that performs a few probes before - // giving up. Measurements done on Gmail indicate that 2 probes - // cover ~93% of loads from dictionaries. - for (int i = 0; i < kInlinedProbes; i++) { - // Compute the masked index: (hash + i + i * i) & mask. - __ mov(r0, FieldOperand(name, Name::kHashFieldOffset)); - __ shr(r0, Name::kHashShift); - if (i > 0) { - __ add(r0, Immediate(NameDictionary::GetProbeOffset(i))); - } - __ and_(r0, r1); - - // Scale the index by multiplying by the entry size. - STATIC_ASSERT(NameDictionary::kEntrySize == 3); - __ lea(r0, Operand(r0, r0, times_2, 0)); // r0 = r0 * 3 - - // Check if the key is identical to the name. - __ cmp(name, Operand(elements, - r0, - times_4, - kElementsStartOffset - kHeapObjectTag)); - __ j(equal, done); - } - - NameDictionaryLookupStub stub(masm->isolate(), elements, r1, r0, - POSITIVE_LOOKUP); - __ push(name); - __ mov(r0, FieldOperand(name, Name::kHashFieldOffset)); - __ shr(r0, Name::kHashShift); - __ push(r0); - __ CallStub(&stub); - - __ test(r1, r1); - __ j(zero, miss); - __ jmp(done); -} - - void NameDictionaryLookupStub::Generate(MacroAssembler* masm) { // This stub overrides SometimesSetsUpAFrame() to return false. That means // we cannot call anything that could cause a GC from this stub. diff --git a/src/x87/code-stubs-x87.h b/src/x87/code-stubs-x87.h index a5c7563d29..9aeae46728 100644 --- a/src/x87/code-stubs-x87.h +++ b/src/x87/code-stubs-x87.h @@ -58,14 +58,6 @@ class NameDictionaryLookupStub: public PlatformCodeStub { Handle name, Register r0); - static void GeneratePositiveLookup(MacroAssembler* masm, - Label* miss, - Label* done, - Register elements, - Register name, - Register r0, - Register r1); - bool SometimesSetsUpAFrame() override { return false; } private: