Commit 85f7663a authored by Marja Hölttä's avatar Marja Hölttä Committed by Commit Bot

[reland] [in-place weak refs] Replace WeakCells in FeedbackVector.

Previous version: https://chromium-review.googlesource.com/1049606

This version is exactly the same as the previous; a bugfix
( https://chromium-review.googlesource.com/c/v8/v8/+/1069127 ) makes
relanding possible.

BUG=v8:7308
TBR=ishell@chromium.org, tebbi@chromium.org, leszeks@chromium.org, ulan@chromium.org

Change-Id: If7d455ceb6af0505a44b4fc52c52143e51cd115a
Reviewed-on: https://chromium-review.googlesource.com/1070027Reviewed-by: 's avatarMarja Hölttä <marja@chromium.org>
Commit-Queue: Marja Hölttä <marja@chromium.org>
Cr-Commit-Position: refs/heads/master@{#53296}
parent 90f6ce12
......@@ -1740,6 +1740,12 @@ TNode<HeapObject> CodeStubAssembler::ToStrongHeapObject(
return ReinterpretCast<HeapObject>(value);
}
TNode<HeapObject> CodeStubAssembler::ToStrongHeapObject(
TNode<MaybeObject> value, Label* if_not_strong) {
GotoIfNot(IsStrongHeapObject(value), if_not_strong);
return ToStrongHeapObject(value);
}
TNode<BoolT> CodeStubAssembler::IsWeakOrClearedHeapObject(
TNode<MaybeObject> value) {
return WordEqual(WordAnd(BitcastMaybeObjectToWord(value),
......@@ -1773,6 +1779,20 @@ TNode<HeapObject> CodeStubAssembler::ToWeakHeapObject(TNode<MaybeObject> value,
return ToWeakHeapObject(value);
}
TNode<BoolT> CodeStubAssembler::IsWeakReferenceTo(TNode<MaybeObject> object,
TNode<Object> value) {
return WordEqual(WordAnd(BitcastMaybeObjectToWord(object),
IntPtrConstant(~kWeakHeapObjectMask)),
BitcastTaggedToWord(value));
}
TNode<BoolT> CodeStubAssembler::IsNotWeakReferenceTo(TNode<MaybeObject> object,
TNode<Object> value) {
return WordNotEqual(WordAnd(BitcastMaybeObjectToWord(object),
IntPtrConstant(~kWeakHeapObjectMask)),
BitcastTaggedToWord(value));
}
TNode<BoolT> CodeStubAssembler::IsObject(TNode<MaybeObject> value) {
return WordNotEqual(WordAnd(BitcastMaybeObjectToWord(value),
IntPtrConstant(kHeapObjectTagMask)),
......@@ -9192,20 +9212,12 @@ TNode<AllocationSite> CodeStubAssembler::CreateAllocationSiteInFeedbackVector(
return CAST(site);
}
Node* CodeStubAssembler::CreateWeakCellInFeedbackVector(Node* feedback_vector,
Node* slot,
Node* value) {
Node* size = IntPtrConstant(WeakCell::kSize);
Node* cell = Allocate(size, CodeStubAssembler::kPretenured);
// Initialize the WeakCell.
DCHECK(Heap::RootIsImmortalImmovable(Heap::kWeakCellMapRootIndex));
StoreMapNoWriteBarrier(cell, Heap::kWeakCellMapRootIndex);
StoreObjectField(cell, WeakCell::kValueOffset, value);
// Store the WeakCell in the feedback vector.
StoreFeedbackVectorSlot(feedback_vector, slot, cell);
return cell;
TNode<MaybeObject> CodeStubAssembler::StoreWeakReferenceInFeedbackVector(
SloppyTNode<FeedbackVector> feedback_vector, SloppyTNode<IntPtrT> slot,
TNode<HeapObject> value) {
TNode<MaybeObject> weak_value = MakeWeak(value);
StoreFeedbackVectorSlot(feedback_vector, slot, weak_value);
return weak_value;
}
Node* CodeStubAssembler::BuildFastLoop(
......
......@@ -679,6 +679,8 @@ class V8_EXPORT_PRIVATE CodeStubAssembler : public compiler::CodeAssembler {
return IsStrongHeapObject(ReinterpretCast<MaybeObject>(value));
}
TNode<HeapObject> ToStrongHeapObject(TNode<MaybeObject> value);
TNode<HeapObject> ToStrongHeapObject(TNode<MaybeObject> value,
Label* if_not_strong);
TNode<BoolT> IsWeakOrClearedHeapObject(TNode<MaybeObject> value);
TNode<BoolT> IsClearedWeakHeapObject(TNode<MaybeObject> value);
......@@ -690,6 +692,11 @@ class V8_EXPORT_PRIVATE CodeStubAssembler : public compiler::CodeAssembler {
TNode<HeapObject> ToWeakHeapObject(TNode<MaybeObject> value,
Label* if_cleared);
TNode<BoolT> IsWeakReferenceTo(TNode<MaybeObject> object,
TNode<Object> value);
TNode<BoolT> IsNotWeakReferenceTo(TNode<MaybeObject> object,
TNode<Object> value);
// IsObject == true when the MaybeObject is a strong HeapObject or a smi.
TNode<BoolT> IsObject(TNode<MaybeObject> value);
// This variant is for overzealous checking.
......@@ -2139,10 +2146,10 @@ class V8_EXPORT_PRIVATE CodeStubAssembler : public compiler::CodeAssembler {
Node* PageFromAddress(Node* address);
// Create a new weak cell with a specified value and install it into a
// feedback vector.
Node* CreateWeakCellInFeedbackVector(Node* feedback_vector, Node* slot,
Node* value);
// Store a weak in-place reference into the FeedbackVector.
TNode<MaybeObject> StoreWeakReferenceInFeedbackVector(
SloppyTNode<FeedbackVector> feedback_vector, SloppyTNode<IntPtrT> slot,
TNode<HeapObject> value);
// Create a new AllocationSite and install it into a feedback vector.
TNode<AllocationSite> CreateAllocationSiteInFeedbackVector(
......
......@@ -1619,14 +1619,15 @@ void BytecodeGraphBuilder::VisitGetTemplateObject() {
FeedbackNexus nexus(feedback_vector(), slot);
Handle<JSArray> cached_value;
if (nexus.GetFeedback() == Smi::kZero) {
if (nexus.GetFeedback() == MaybeObject::FromSmi(Smi::kZero)) {
// It's not observable when the template object is created, so we
// can just create it eagerly during graph building and bake in
// the JSArray constant here.
cached_value = TemplateObjectDescription::CreateTemplateObject(description);
nexus.vector()->Set(slot, *cached_value);
} else {
cached_value = handle(JSArray::cast(nexus.GetFeedback()));
cached_value =
handle(JSArray::cast(nexus.GetFeedback()->ToStrongHeapObject()));
}
Node* template_object = jsgraph()->HeapConstant(cached_value);
......
......@@ -3273,15 +3273,14 @@ Reduction JSCallReducer::ReduceJSCall(Node* node) {
return NoChange();
}
Handle<Object> feedback(nexus.GetFeedback(), isolate());
if (feedback->IsWeakCell()) {
HeapObject* heap_object;
if (nexus.GetFeedback()->ToWeakHeapObject(&heap_object)) {
Handle<HeapObject> feedback(heap_object, isolate());
// Check if we want to use CallIC feedback here.
if (!ShouldUseCallICFeedback(target)) return NoChange();
Handle<WeakCell> cell = Handle<WeakCell>::cast(feedback);
if (cell->value()->IsCallable()) {
Node* target_function =
jsgraph()->Constant(handle(cell->value(), isolate()));
if (feedback->IsCallable()) {
Node* target_function = jsgraph()->Constant(feedback);
// Check that the {target} is still the {target_function}.
Node* check = graph()->NewNode(simplified()->ReferenceEqual(), target,
......@@ -3650,13 +3649,15 @@ Reduction JSCallReducer::ReduceJSConstruct(Node* node) {
return NoChange();
}
Handle<Object> feedback(nexus.GetFeedback(), isolate());
if (feedback->IsAllocationSite()) {
HeapObject* feedback_object;
if (nexus.GetFeedback()->ToStrongHeapObject(&feedback_object) &&
feedback_object->IsAllocationSite()) {
// The feedback is an AllocationSite, which means we have called the
// Array function and collected transition (and pretenuring) feedback
// for the resulting arrays. This has to be kept in sync with the
// implementation in Ignition.
Handle<AllocationSite> site = Handle<AllocationSite>::cast(feedback);
Handle<AllocationSite> site(AllocationSite::cast(feedback_object),
isolate());
// Retrieve the Array function from the {node}.
Node* array_function = jsgraph()->HeapConstant(
......@@ -3678,12 +3679,11 @@ Reduction JSCallReducer::ReduceJSConstruct(Node* node) {
NodeProperties::ReplaceValueInput(node, array_function, 1);
NodeProperties::ChangeOp(node, javascript()->CreateArray(arity, site));
return Changed(node);
} else if (feedback->IsWeakCell() &&
} else if (nexus.GetFeedback()->ToWeakHeapObject(&feedback_object) &&
!HeapObjectMatcher(new_target).HasValue()) {
Handle<WeakCell> cell = Handle<WeakCell>::cast(feedback);
if (cell->value()->IsConstructor()) {
Node* new_target_feedback =
jsgraph()->Constant(handle(cell->value(), isolate()));
Handle<HeapObject> object(feedback_object, isolate());
if (object->IsConstructor()) {
Node* new_target_feedback = jsgraph()->Constant(object);
// Check that the {new_target} is still the {new_target_feedback}.
Node* check = graph()->NewNode(simplified()->ReferenceEqual(),
......
......@@ -249,8 +249,8 @@ ForInHint ForInHintFromFeedback(int type_feedback) {
void FeedbackVector::ComputeCounts(int* with_type_info, int* generic,
int* vector_ic_count) {
Object* megamorphic_sentinel =
*FeedbackVector::MegamorphicSentinel(GetIsolate());
MaybeObject* megamorphic_sentinel = MaybeObject::FromObject(
*FeedbackVector::MegamorphicSentinel(GetIsolate()));
int with = 0;
int gen = 0;
int total = 0;
......@@ -259,7 +259,7 @@ void FeedbackVector::ComputeCounts(int* with_type_info, int* generic,
FeedbackSlot slot = iter.Next();
FeedbackSlotKind kind = iter.kind();
Object* const obj = Get(slot)->ToStrongHeapObject();
MaybeObject* const obj = Get(slot);
AssertNoLegacyTypes(obj);
switch (kind) {
case FeedbackSlotKind::kCall:
......@@ -277,7 +277,10 @@ void FeedbackVector::ComputeCounts(int* with_type_info, int* generic,
case FeedbackSlotKind::kStoreInArrayLiteral:
case FeedbackSlotKind::kStoreDataPropertyInLiteral:
case FeedbackSlotKind::kTypeProfile: {
if (obj->IsWeakCell() || obj->IsWeakFixedArray() || obj->IsString()) {
HeapObject* heap_object;
if (obj->IsWeakOrClearedHeapObject() ||
(obj->ToStrongHeapObject(&heap_object) &&
(heap_object->IsWeakFixedArray() || heap_object->IsString()))) {
with++;
} else if (obj == megamorphic_sentinel) {
gen++;
......@@ -287,7 +290,7 @@ void FeedbackVector::ComputeCounts(int* with_type_info, int* generic,
break;
}
case FeedbackSlotKind::kBinaryOp: {
int const feedback = Smi::ToInt(obj);
int const feedback = Smi::ToInt(obj->ToSmi());
BinaryOperationHint hint = BinaryOperationHintFromFeedback(feedback);
if (hint == BinaryOperationHint::kAny) {
gen++;
......@@ -299,20 +302,19 @@ void FeedbackVector::ComputeCounts(int* with_type_info, int* generic,
break;
}
case FeedbackSlotKind::kCompareOp: {
int const feedback = Smi::ToInt(obj);
CompareOperationHint hint =
CompareOperationHintFromFeedback(feedback);
if (hint == CompareOperationHint::kAny) {
gen++;
}
if (hint != CompareOperationHint::kNone) {
with++;
}
total++;
int const feedback = Smi::ToInt(obj->ToSmi());
CompareOperationHint hint = CompareOperationHintFromFeedback(feedback);
if (hint == CompareOperationHint::kAny) {
gen++;
}
if (hint != CompareOperationHint::kNone) {
with++;
}
total++;
break;
}
case FeedbackSlotKind::kForIn: {
int const feedback = Smi::ToInt(obj);
int const feedback = Smi::ToInt(obj->ToSmi());
ForInHint hint = ForInHintFromFeedback(feedback);
if (hint == ForInHint::kAny) {
gen++;
......@@ -324,7 +326,7 @@ void FeedbackVector::ComputeCounts(int* with_type_info, int* generic,
break;
}
case FeedbackSlotKind::kInstanceOf: {
if (obj->IsWeakCell()) {
if (obj->IsWeakOrClearedHeapObject()) {
with++;
} else if (obj == megamorphic_sentinel) {
gen++;
......@@ -384,8 +386,8 @@ int FeedbackMetadataIterator::entry_size() const {
return FeedbackMetadata::GetSlotSize(kind());
}
Object* FeedbackNexus::GetFeedback() const {
Object* feedback = vector()->Get(slot())->ToObject();
MaybeObject* FeedbackNexus::GetFeedback() const {
MaybeObject* feedback = vector()->Get(slot());
FeedbackVector::AssertNoLegacyTypes(feedback);
return feedback;
}
......@@ -400,8 +402,12 @@ MaybeObject* FeedbackNexus::GetFeedbackExtra() const {
}
void FeedbackNexus::SetFeedback(Object* feedback, WriteBarrierMode mode) {
SetFeedback(MaybeObject::FromObject(feedback));
}
void FeedbackNexus::SetFeedback(MaybeObject* feedback, WriteBarrierMode mode) {
FeedbackVector::AssertNoLegacyTypes(feedback);
vector()->Set(slot(), MaybeObject::FromObject(feedback), mode);
vector()->Set(slot(), feedback, mode);
}
void FeedbackNexus::SetFeedbackExtra(Object* feedback_extra,
......@@ -409,7 +415,7 @@ void FeedbackNexus::SetFeedbackExtra(Object* feedback_extra,
#ifdef DEBUG
FeedbackSlotKind kind = vector()->GetKind(slot());
DCHECK_LT(1, FeedbackMetadata::GetSlotSize(kind));
FeedbackVector::AssertNoLegacyTypes(feedback_extra);
FeedbackVector::AssertNoLegacyTypes(MaybeObject::FromObject(feedback_extra));
#endif
int index = vector()->GetIndex(slot()) + 1;
vector()->set(index, MaybeObject::FromObject(feedback_extra), mode);
......@@ -418,7 +424,7 @@ void FeedbackNexus::SetFeedbackExtra(Object* feedback_extra,
void FeedbackNexus::SetFeedbackExtra(MaybeObject* feedback_extra,
WriteBarrierMode mode) {
#ifdef DEBUG
FeedbackVector::AssertNoLegacyTypes(feedback_extra->GetHeapObjectOrSmi());
FeedbackVector::AssertNoLegacyTypes(feedback_extra);
#endif
int index = vector()->GetIndex(slot()) + 1;
vector()->set(index, feedback_extra, mode);
......
This diff is collapsed.
......@@ -248,7 +248,7 @@ class FeedbackVector : public HeapObject {
void Print();
#endif // OBJECT_PRINT
static void AssertNoLegacyTypes(Object* object);
static void AssertNoLegacyTypes(MaybeObject* object);
DECL_PRINTER(FeedbackVector)
DECL_VERIFIER(FeedbackVector)
......@@ -609,7 +609,7 @@ class FeedbackNexus final {
void ConfigurePremonomorphic();
bool ConfigureMegamorphic(IcCheckType property_type);
inline Object* GetFeedback() const;
inline MaybeObject* GetFeedback() const;
inline MaybeObject* GetFeedbackExtra() const;
inline Isolate* GetIsolate() const;
......@@ -684,6 +684,8 @@ class FeedbackNexus final {
protected:
inline void SetFeedback(Object* feedback,
WriteBarrierMode mode = UPDATE_WRITE_BARRIER);
inline void SetFeedback(MaybeObject* feedback,
WriteBarrierMode mode = UPDATE_WRITE_BARRIER);
inline void SetFeedbackExtra(Object* feedback_extra,
WriteBarrierMode mode = UPDATE_WRITE_BARRIER);
inline void SetFeedbackExtra(MaybeObject* feedback_extra,
......
......@@ -102,10 +102,11 @@ void IncrementalMarking::RecordWriteSlow(HeapObject* obj,
}
}
int IncrementalMarking::RecordWriteFromCode(HeapObject* obj, Object** slot,
int IncrementalMarking::RecordWriteFromCode(HeapObject* obj, MaybeObject** slot,
Isolate* isolate) {
DCHECK(obj->IsHeapObject());
isolate->heap()->incremental_marking()->RecordWrite(obj, slot, *slot);
isolate->heap()->incremental_marking()->RecordMaybeWeakWrite(obj, slot,
*slot);
// Called by RecordWriteCodeStubAssembler, which doesnt accept void type
return 0;
}
......
......@@ -196,7 +196,7 @@ class V8_EXPORT_PRIVATE IncrementalMarking {
inline void RestartIfNotMarking();
static int RecordWriteFromCode(HeapObject* obj, Object** slot,
static int RecordWriteFromCode(HeapObject* obj, MaybeObject** slot,
Isolate* isolate);
// Record a slot for compaction. Returns false for objects that are
......
This diff is collapsed.
......@@ -133,7 +133,7 @@ class AccessorAssembler : public CodeStubAssembler {
// logic not inlined into Ignition bytecode handlers.
void LoadIC(const LoadICParameters* p);
void LoadIC_Noninlined(const LoadICParameters* p, Node* receiver_map,
Node* feedback, Variable* var_handler,
TNode<HeapObject> feedback, Variable* var_handler,
Label* if_handler, Label* miss, ExitPoint* exit_point);
Node* LoadDescriptorValue(Node* map, Node* descriptor);
......@@ -153,9 +153,10 @@ class AccessorAssembler : public CodeStubAssembler {
// IC dispatcher behavior.
// Checks monomorphic case. Returns {feedback} entry of the vector.
Node* TryMonomorphicCase(Node* slot, Node* vector, Node* receiver_map,
Label* if_handler,
TVariable<MaybeObject>* var_handler, Label* if_miss);
TNode<MaybeObject> TryMonomorphicCase(Node* slot, Node* vector,
Node* receiver_map, Label* if_handler,
TVariable<MaybeObject>* var_handler,
Label* if_miss);
void HandlePolymorphicCase(Node* receiver_map, TNode<WeakFixedArray> feedback,
Label* if_handler,
TVariable<MaybeObject>* var_handler,
......
This diff is collapsed.
......@@ -3016,22 +3016,14 @@ TEST(IncrementalMarkingPreservesMonomorphicCallIC) {
CHECK_EQ(expected_slots, feedback_helper.slot_count());
int slot1 = 0;
int slot2 = 1;
CHECK(feedback_vector->Get(feedback_helper.slot(slot1))
->ToStrongHeapObject()
->IsWeakCell());
CHECK(feedback_vector->Get(feedback_helper.slot(slot2))
->ToStrongHeapObject()
->IsWeakCell());
CHECK(feedback_vector->Get(feedback_helper.slot(slot1))->IsWeakHeapObject());
CHECK(feedback_vector->Get(feedback_helper.slot(slot2))->IsWeakHeapObject());
heap::SimulateIncrementalMarking(CcTest::heap());
CcTest::CollectAllGarbage();
CHECK(!WeakCell::cast(feedback_vector->Get(feedback_helper.slot(slot1))
->ToStrongHeapObject())
->cleared());
CHECK(!WeakCell::cast(feedback_vector->Get(feedback_helper.slot(slot2))
->ToStrongHeapObject())
->cleared());
feedback_vector->Get(feedback_helper.slot(slot1))->IsWeakHeapObject();
feedback_vector->Get(feedback_helper.slot(slot2))->IsWeakHeapObject();
}
......@@ -3060,12 +3052,12 @@ TEST(IncrementalMarkingPreservesMonomorphicConstructor) {
CcTest::global()->Get(ctx, v8_str("f")).ToLocalChecked())));
Handle<FeedbackVector> vector(f->feedback_vector());
CHECK(vector->Get(FeedbackSlot(0))->ToStrongHeapObject()->IsWeakCell());
CHECK(vector->Get(FeedbackSlot(0))->IsWeakOrClearedHeapObject());
heap::SimulateIncrementalMarking(CcTest::heap());
CcTest::CollectAllGarbage();
CHECK(vector->Get(FeedbackSlot(0))->ToStrongHeapObject()->IsWeakCell());
CHECK(vector->Get(FeedbackSlot(0))->IsWeakOrClearedHeapObject());
}
TEST(IncrementalMarkingPreservesMonomorphicIC) {
......@@ -3987,19 +3979,19 @@ TEST(WeakFunctionInConstructor) {
Handle<FeedbackVector> feedback_vector =
Handle<FeedbackVector>(createObj->feedback_vector(), CcTest::i_isolate());
for (int i = 0; i < 20; i++) {
Object* slot_value = feedback_vector->Get(FeedbackSlot(0))->ToObject();
CHECK(slot_value->IsWeakCell());
if (WeakCell::cast(slot_value)->cleared()) break;
MaybeObject* slot_value = feedback_vector->Get(FeedbackSlot(0));
CHECK(slot_value->IsWeakOrClearedHeapObject());
if (slot_value->IsClearedWeakHeapObject()) break;
CcTest::CollectAllGarbage();
}
Object* slot_value = feedback_vector->Get(FeedbackSlot(0))->ToObject();
CHECK(slot_value->IsWeakCell() && WeakCell::cast(slot_value)->cleared());
MaybeObject* slot_value = feedback_vector->Get(FeedbackSlot(0));
CHECK(slot_value->IsClearedWeakHeapObject());
CompileRun(
"function coat() { this.x = 6; }"
"createObj(coat);");
slot_value = feedback_vector->Get(FeedbackSlot(0))->ToObject();
CHECK(slot_value->IsWeakCell() && !WeakCell::cast(slot_value)->cleared());
slot_value = feedback_vector->Get(FeedbackSlot(0));
CHECK(slot_value->IsWeakHeapObject());
}
......
......@@ -313,8 +313,11 @@ TEST(FeedbackVectorPreservedAcrossRecompiles) {
CHECK(!feedback_vector->is_empty());
FeedbackSlot slot_for_a(0);
MaybeObject* object = feedback_vector->Get(slot_for_a);
CHECK(object->ToStrongHeapObject()->IsWeakCell() &&
WeakCell::cast(object->ToStrongHeapObject())->value()->IsJSFunction());
{
HeapObject* heap_object;
CHECK(object->ToWeakHeapObject(&heap_object));
CHECK(heap_object->IsJSFunction());
}
CompileRun("%OptimizeFunctionOnNextCall(f); f(fun1);");
......@@ -322,8 +325,11 @@ TEST(FeedbackVectorPreservedAcrossRecompiles) {
// of the full code.
CHECK(f->IsOptimized());
object = f->feedback_vector()->Get(slot_for_a);
CHECK(object->ToStrongHeapObject()->IsWeakCell() &&
WeakCell::cast(object->ToStrongHeapObject())->value()->IsJSFunction());
{
HeapObject* heap_object;
CHECK(object->ToWeakHeapObject(&heap_object));
CHECK(heap_object->IsJSFunction());
}
}
......
......@@ -202,8 +202,9 @@ TEST(VectorCallFeedback) {
FeedbackNexus nexus(feedback_vector, slot);
CHECK_EQ(MONOMORPHIC, nexus.StateFromFeedback());
CHECK(nexus.GetFeedback()->IsWeakCell());
CHECK(*foo == WeakCell::cast(nexus.GetFeedback())->value());
HeapObject* heap_object;
CHECK(nexus.GetFeedback()->ToWeakHeapObject(&heap_object));
CHECK_EQ(*foo, heap_object);
CcTest::CollectAllGarbage();
// It should stay monomorphic even after a GC.
......@@ -226,9 +227,9 @@ TEST(VectorCallFeedbackForArray) {
FeedbackNexus nexus(feedback_vector, slot);
CHECK_EQ(MONOMORPHIC, nexus.StateFromFeedback());
CHECK(nexus.GetFeedback()->IsWeakCell());
CHECK(*isolate->array_function() ==
WeakCell::cast(nexus.GetFeedback())->value());
HeapObject* heap_object;
CHECK(nexus.GetFeedback()->ToWeakHeapObject(&heap_object));
CHECK_EQ(*isolate->array_function(), heap_object);
CcTest::CollectAllGarbage();
// It should stay monomorphic even after a GC.
......@@ -283,7 +284,7 @@ TEST(VectorConstructCounts) {
FeedbackNexus nexus(feedback_vector, slot);
CHECK_EQ(MONOMORPHIC, nexus.StateFromFeedback());
CHECK(feedback_vector->Get(slot)->ToStrongHeapObject()->IsWeakCell());
CHECK(feedback_vector->Get(slot)->IsWeakHeapObject());
CompileRun("f(Foo); f(Foo);");
CHECK_EQ(MONOMORPHIC, nexus.StateFromFeedback());
......
......@@ -2579,7 +2579,7 @@ TEST(TrackHeapAllocationsWithInlining) {
const char* names[] = {"", "start", "f_0_0"};
AllocationTraceNode* node = FindNode(tracker, ArrayVector(names));
CHECK(node);
CHECK_GE(node->allocation_count(), 10u);
CHECK_GE(node->allocation_count(), 8u);
CHECK_GE(node->allocation_size(), 4 * node->allocation_count());
heap_profiler->StopTrackingHeapObjects();
}
......
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