From 3b400fcb9b234cd9a3e6e90a2b3e3f94ec3ebbd9 Mon Sep 17 00:00:00 2001 From: "balazs.kilvady" Date: Wed, 4 Feb 2015 08:05:11 -0800 Subject: [PATCH] MIPS: Retry "Use a WeakCell in the CallIC type vector." Port 6fc97a19653e03a891d3cd397069d5a10b9ab325 Original commit message: The first try failed because I needed to make a better distinction between clearing ICs according to policy at GC time or unconditional clearing (say, via %ClearFunctionTypeFeedback). It was also blocked by an issue in super constructor calls. This fix (https://codereview.chromium.org/892113002/) needs to land before checking in this CL. BUG= Review URL: https://codereview.chromium.org/896223002 Cr-Commit-Position: refs/heads/master@{#26432} --- src/mips/code-stubs-mips.cc | 43 +++++++++++++++++++++++------- src/mips/interface-descriptors-mips.cc | 14 +++++++++- src/mips64/code-stubs-mips64.cc | 43 +++++++++++++++++++++++------- src/mips64/interface-descriptors-mips64.cc | 14 +++++++++- 4 files changed, 92 insertions(+), 22 deletions(-) diff --git a/src/mips/code-stubs-mips.cc b/src/mips/code-stubs-mips.cc index b0b3272..b7e75ec 100644 --- a/src/mips/code-stubs-mips.cc +++ b/src/mips/code-stubs-mips.cc @@ -1001,6 +1001,7 @@ void CodeStub::GenerateStubsAheadOfTime(Isolate* isolate) { StubFailureTrampolineStub::GenerateAheadOfTime(isolate); ArrayConstructorStubBase::GenerateStubsAheadOfTime(isolate); CreateAllocationSiteStub::GenerateAheadOfTime(isolate); + CreateWeakCellStub::GenerateAheadOfTime(isolate); BinaryOpICStub::GenerateAheadOfTime(isolate); StoreRegistersStateStub::GenerateAheadOfTime(isolate); RestoreRegistersStateStub::GenerateAheadOfTime(isolate); @@ -2797,7 +2798,27 @@ void CallICStub::Generate(MacroAssembler* masm) { __ sll(t0, a3, kPointerSizeLog2 - kSmiTagSize); __ Addu(t0, a2, Operand(t0)); __ lw(t0, FieldMemOperand(t0, FixedArray::kHeaderSize)); - __ Branch(&extra_checks_or_miss, ne, a1, Operand(t0)); + + // We don't know that we have a weak cell. We might have a private symbol + // or an AllocationSite, but the memory is safe to examine. + // AllocationSite::kTransitionInfoOffset - contains a Smi or pointer to + // FixedArray. + // WeakCell::kValueOffset - contains a JSFunction or Smi(0) + // Symbol::kHashFieldSlot - if the low bit is 1, then the hash is not + // computed, meaning that it can't appear to be a pointer. If the low bit is + // 0, then hash is computed, but the 0 bit prevents the field from appearing + // to be a pointer. + STATIC_ASSERT(WeakCell::kSize >= kPointerSize); + STATIC_ASSERT(AllocationSite::kTransitionInfoOffset == + WeakCell::kValueOffset && + WeakCell::kValueOffset == Symbol::kHashFieldSlot); + + __ lw(t1, FieldMemOperand(t0, WeakCell::kValueOffset)); + __ Branch(&extra_checks_or_miss, ne, a1, Operand(t1)); + + // The compare above could have been a SMI/SMI comparison. Guard against this + // convincing us that we have a monomorphic JSFunction. + __ JumpIfSmi(a1, &extra_checks_or_miss); __ bind(&have_js_function); if (CallAsMethod()) { @@ -2874,16 +2895,18 @@ void CallICStub::Generate(MacroAssembler* masm) { __ Addu(t0, t0, Operand(Smi::FromInt(1))); __ sw(t0, FieldMemOperand(a2, with_types_offset)); - // Store the function. - __ sll(t0, a3, kPointerSizeLog2 - kSmiTagSize); - __ Addu(t0, a2, Operand(t0)); - __ Addu(t0, t0, Operand(FixedArray::kHeaderSize - kHeapObjectTag)); - __ sw(a1, MemOperand(t0, 0)); + // Store the function. Use a stub since we need a frame for allocation. + // a2 - vector + // a3 - slot + // a1 - function + { + FrameScope scope(masm, StackFrame::INTERNAL); + CreateWeakCellStub create_stub(masm->isolate()); + __ Push(a1); + __ CallStub(&create_stub); + __ Pop(a1); + } - // Update the write barrier. - __ mov(t1, a1); - __ RecordWrite(a2, t0, t1, kRAHasNotBeenSaved, kDontSaveFPRegs, - EMIT_REMEMBERED_SET, OMIT_SMI_CHECK); __ Branch(&have_js_function); // We are here because tracing is on or we encountered a MISS case we can't diff --git a/src/mips/interface-descriptors-mips.cc b/src/mips/interface-descriptors-mips.cc index b2ac478..b8cae81 100644 --- a/src/mips/interface-descriptors-mips.cc +++ b/src/mips/interface-descriptors-mips.cc @@ -98,7 +98,19 @@ void FastCloneShallowObjectDescriptor::Initialize( void CreateAllocationSiteDescriptor::Initialize( CallInterfaceDescriptorData* data) { Register registers[] = {cp, a2, a3}; - data->Initialize(arraysize(registers), registers, NULL); + Representation representations[] = {Representation::Tagged(), + Representation::Tagged(), + Representation::Smi()}; + data->Initialize(arraysize(registers), registers, representations); +} + + +void CreateWeakCellDescriptor::Initialize(CallInterfaceDescriptorData* data) { + Register registers[] = {cp, a2, a3, a1}; + Representation representations[] = { + Representation::Tagged(), Representation::Tagged(), Representation::Smi(), + Representation::Tagged()}; + data->Initialize(arraysize(registers), registers, representations); } diff --git a/src/mips64/code-stubs-mips64.cc b/src/mips64/code-stubs-mips64.cc index efb1fd1..454d6fb 100644 --- a/src/mips64/code-stubs-mips64.cc +++ b/src/mips64/code-stubs-mips64.cc @@ -997,6 +997,7 @@ void CodeStub::GenerateStubsAheadOfTime(Isolate* isolate) { StubFailureTrampolineStub::GenerateAheadOfTime(isolate); ArrayConstructorStubBase::GenerateStubsAheadOfTime(isolate); CreateAllocationSiteStub::GenerateAheadOfTime(isolate); + CreateWeakCellStub::GenerateAheadOfTime(isolate); BinaryOpICStub::GenerateAheadOfTime(isolate); StoreRegistersStateStub::GenerateAheadOfTime(isolate); RestoreRegistersStateStub::GenerateAheadOfTime(isolate); @@ -2872,7 +2873,27 @@ void CallICStub::Generate(MacroAssembler* masm) { __ dsrl(a4, a3, 32 - kPointerSizeLog2); __ Daddu(a4, a2, Operand(a4)); __ ld(a4, FieldMemOperand(a4, FixedArray::kHeaderSize)); - __ Branch(&extra_checks_or_miss, ne, a1, Operand(a4)); + + // We don't know that we have a weak cell. We might have a private symbol + // or an AllocationSite, but the memory is safe to examine. + // AllocationSite::kTransitionInfoOffset - contains a Smi or pointer to + // FixedArray. + // WeakCell::kValueOffset - contains a JSFunction or Smi(0) + // Symbol::kHashFieldSlot - if the low bit is 1, then the hash is not + // computed, meaning that it can't appear to be a pointer. If the low bit is + // 0, then hash is computed, but the 0 bit prevents the field from appearing + // to be a pointer. + STATIC_ASSERT(WeakCell::kSize >= kPointerSize); + STATIC_ASSERT(AllocationSite::kTransitionInfoOffset == + WeakCell::kValueOffset && + WeakCell::kValueOffset == Symbol::kHashFieldSlot); + + __ ld(a5, FieldMemOperand(a4, WeakCell::kValueOffset)); + __ Branch(&extra_checks_or_miss, ne, a1, Operand(a5)); + + // The compare above could have been a SMI/SMI comparison. Guard against this + // convincing us that we have a monomorphic JSFunction. + __ JumpIfSmi(a1, &extra_checks_or_miss); __ bind(&have_js_function); if (CallAsMethod()) { @@ -2949,16 +2970,18 @@ void CallICStub::Generate(MacroAssembler* masm) { __ Daddu(a4, a4, Operand(Smi::FromInt(1))); __ sd(a4, FieldMemOperand(a2, with_types_offset)); - // Store the function. - __ dsrl(a4, a3, 32 - kPointerSizeLog2); - __ Daddu(a4, a2, Operand(a4)); - __ Daddu(a4, a4, Operand(FixedArray::kHeaderSize - kHeapObjectTag)); - __ sd(a1, MemOperand(a4, 0)); + // Store the function. Use a stub since we need a frame for allocation. + // a2 - vector + // a3 - slot + // a1 - function + { + FrameScope scope(masm, StackFrame::INTERNAL); + CreateWeakCellStub create_stub(masm->isolate()); + __ Push(a1); + __ CallStub(&create_stub); + __ Pop(a1); + } - // Update the write barrier. - __ mov(a5, a1); - __ RecordWrite(a2, a4, a5, kRAHasNotBeenSaved, kDontSaveFPRegs, - EMIT_REMEMBERED_SET, OMIT_SMI_CHECK); __ Branch(&have_js_function); // We are here because tracing is on or we encountered a MISS case we can't diff --git a/src/mips64/interface-descriptors-mips64.cc b/src/mips64/interface-descriptors-mips64.cc index d7f0fe5..8d1b9f2 100644 --- a/src/mips64/interface-descriptors-mips64.cc +++ b/src/mips64/interface-descriptors-mips64.cc @@ -98,7 +98,19 @@ void FastCloneShallowObjectDescriptor::Initialize( void CreateAllocationSiteDescriptor::Initialize( CallInterfaceDescriptorData* data) { Register registers[] = {cp, a2, a3}; - data->Initialize(arraysize(registers), registers, NULL); + Representation representations[] = {Representation::Tagged(), + Representation::Tagged(), + Representation::Smi()}; + data->Initialize(arraysize(registers), registers, representations); +} + + +void CreateWeakCellDescriptor::Initialize(CallInterfaceDescriptorData* data) { + Register registers[] = {cp, a2, a3, a1}; + Representation representations[] = { + Representation::Tagged(), Representation::Tagged(), Representation::Smi(), + Representation::Tagged()}; + data->Initialize(arraysize(registers), registers, representations); } -- 2.7.4