Commit 7280426a authored by cdai2's avatar cdai2

X87: Retry "Use a WeakCell in the CallIC type vector."

port 6fc97a19 (r26420)

original commit message:

  Retry "Use a WeakCell in the CallIC type vector."

  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=
R=weiliang.lin@intel.com

Review URL: https://codereview.chromium.org/865713004

Cr-Commit-Position: refs/heads/master@{#26517}
parent 161efc42
...@@ -1932,10 +1932,30 @@ void CallICStub::Generate(MacroAssembler* masm) { ...@@ -1932,10 +1932,30 @@ void CallICStub::Generate(MacroAssembler* masm) {
ParameterCount actual(argc); ParameterCount actual(argc);
// The checks. First, does edi match the recorded monomorphic target? // The checks. First, does edi match the recorded monomorphic target?
__ cmp(edi, FieldOperand(ebx, edx, times_half_pointer_size, __ mov(ecx, FieldOperand(ebx, edx, times_half_pointer_size,
FixedArray::kHeaderSize)); FixedArray::kHeaderSize));
// 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);
__ cmp(edi, FieldOperand(ecx, WeakCell::kValueOffset));
__ j(not_equal, &extra_checks_or_miss); __ j(not_equal, &extra_checks_or_miss);
// The compare above could have been a SMI/SMI comparison. Guard against this
// convincing us that we have a monomorphic JSFunction.
__ JumpIfSmi(edi, &extra_checks_or_miss);
__ bind(&have_js_function); __ bind(&have_js_function);
if (CallAsMethod()) { if (CallAsMethod()) {
EmitContinueIfStrictOrNative(masm, &cont); EmitContinueIfStrictOrNative(masm, &cont);
...@@ -1964,8 +1984,6 @@ void CallICStub::Generate(MacroAssembler* masm) { ...@@ -1964,8 +1984,6 @@ void CallICStub::Generate(MacroAssembler* masm) {
__ bind(&extra_checks_or_miss); __ bind(&extra_checks_or_miss);
Label uninitialized, miss; Label uninitialized, miss;
__ mov(ecx, FieldOperand(ebx, edx, times_half_pointer_size,
FixedArray::kHeaderSize));
__ cmp(ecx, Immediate(TypeFeedbackVector::MegamorphicSentinel(isolate))); __ cmp(ecx, Immediate(TypeFeedbackVector::MegamorphicSentinel(isolate)));
__ j(equal, &slow_start); __ j(equal, &slow_start);
...@@ -2009,15 +2027,18 @@ void CallICStub::Generate(MacroAssembler* masm) { ...@@ -2009,15 +2027,18 @@ void CallICStub::Generate(MacroAssembler* masm) {
// Update stats. // Update stats.
__ add(FieldOperand(ebx, with_types_offset), Immediate(Smi::FromInt(1))); __ add(FieldOperand(ebx, with_types_offset), Immediate(Smi::FromInt(1)));
// Store the function. // Store the function. Use a stub since we need a frame for allocation.
__ mov( // ebx - vector
FieldOperand(ebx, edx, times_half_pointer_size, FixedArray::kHeaderSize), // edx - slot
edi); // edi - function
{
FrameScope scope(masm, StackFrame::INTERNAL);
CreateWeakCellStub create_stub(isolate);
__ push(edi);
__ CallStub(&create_stub);
__ pop(edi);
}
// Update the write barrier.
__ mov(eax, edi);
__ RecordWriteArray(ebx, eax, edx, kDontSaveFPRegs, EMIT_REMEMBERED_SET,
OMIT_SMI_CHECK);
__ jmp(&have_js_function); __ jmp(&have_js_function);
// We are here because tracing is on or we encountered a MISS case we can't // We are here because tracing is on or we encountered a MISS case we can't
...@@ -2073,6 +2094,7 @@ void CodeStub::GenerateStubsAheadOfTime(Isolate* isolate) { ...@@ -2073,6 +2094,7 @@ void CodeStub::GenerateStubsAheadOfTime(Isolate* isolate) {
// It is important that the store buffer overflow stubs are generated first. // It is important that the store buffer overflow stubs are generated first.
ArrayConstructorStubBase::GenerateStubsAheadOfTime(isolate); ArrayConstructorStubBase::GenerateStubsAheadOfTime(isolate);
CreateAllocationSiteStub::GenerateAheadOfTime(isolate); CreateAllocationSiteStub::GenerateAheadOfTime(isolate);
CreateWeakCellStub::GenerateAheadOfTime(isolate);
BinaryOpICStub::GenerateAheadOfTime(isolate); BinaryOpICStub::GenerateAheadOfTime(isolate);
BinaryOpICWithAllocationSiteStub::GenerateAheadOfTime(isolate); BinaryOpICWithAllocationSiteStub::GenerateAheadOfTime(isolate);
} }
......
...@@ -101,7 +101,19 @@ void FastCloneShallowObjectDescriptor::Initialize( ...@@ -101,7 +101,19 @@ void FastCloneShallowObjectDescriptor::Initialize(
void CreateAllocationSiteDescriptor::Initialize( void CreateAllocationSiteDescriptor::Initialize(
CallInterfaceDescriptorData* data) { CallInterfaceDescriptorData* data) {
Register registers[] = {esi, ebx, edx}; Register registers[] = {esi, ebx, edx};
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[] = {esi, ebx, edx, edi};
Representation representations[] = {
Representation::Tagged(), Representation::Tagged(), Representation::Smi(),
Representation::Tagged()};
data->Initialize(arraysize(registers), registers, representations);
} }
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment