[stubs] Port store IC dispatcher to TurboFan.
This CL introduces StoreICTFStub and StoreICTrampolineTFStub and a switch to enable them instead of respective platform stubs. This should ease the split of StoreIC to StoreGlobalIC and StoreIC. StubCache tests now exercise both load and store ICs. BUG=chromium:576312 Review-Url: https://codereview.chromium.org/2163253002 Cr-Commit-Position: refs/heads/master@{#39751}
This commit is contained in:
parent
2c9661a62a
commit
2390243564
@ -108,6 +108,10 @@ Callable CodeFactory::CallICInOptimizedCode(Isolate* isolate, int argc,
|
||||
|
||||
// static
|
||||
Callable CodeFactory::StoreIC(Isolate* isolate, LanguageMode language_mode) {
|
||||
if (FLAG_tf_store_ic_stub) {
|
||||
StoreICTrampolineTFStub stub(isolate, StoreICState(language_mode));
|
||||
return make_callable(stub);
|
||||
}
|
||||
StoreICTrampolineStub stub(isolate, StoreICState(language_mode));
|
||||
return make_callable(stub);
|
||||
}
|
||||
@ -115,6 +119,10 @@ Callable CodeFactory::StoreIC(Isolate* isolate, LanguageMode language_mode) {
|
||||
// static
|
||||
Callable CodeFactory::StoreICInOptimizedCode(Isolate* isolate,
|
||||
LanguageMode language_mode) {
|
||||
if (FLAG_tf_store_ic_stub) {
|
||||
StoreICTFStub stub(isolate, StoreICState(language_mode));
|
||||
return make_callable(stub);
|
||||
}
|
||||
StoreICStub stub(isolate, StoreICState(language_mode));
|
||||
return make_callable(stub);
|
||||
}
|
||||
|
@ -3752,23 +3752,23 @@ compiler::Node* CodeStubAssembler::LoadReceiverMap(compiler::Node* receiver) {
|
||||
}
|
||||
|
||||
compiler::Node* CodeStubAssembler::TryMonomorphicCase(
|
||||
const LoadICParameters* p, compiler::Node* receiver_map, Label* if_handler,
|
||||
Variable* var_handler, Label* if_miss) {
|
||||
compiler::Node* slot, compiler::Node* vector, compiler::Node* receiver_map,
|
||||
Label* if_handler, Variable* var_handler, Label* if_miss) {
|
||||
DCHECK_EQ(MachineRepresentation::kTagged, var_handler->rep());
|
||||
|
||||
// TODO(ishell): add helper class that hides offset computations for a series
|
||||
// of loads.
|
||||
int32_t header_size = FixedArray::kHeaderSize - kHeapObjectTag;
|
||||
Node* offset = ElementOffsetFromIndex(p->slot, FAST_HOLEY_ELEMENTS,
|
||||
Node* offset = ElementOffsetFromIndex(slot, FAST_HOLEY_ELEMENTS,
|
||||
SMI_PARAMETERS, header_size);
|
||||
Node* feedback = Load(MachineType::AnyTagged(), p->vector, offset);
|
||||
Node* feedback = Load(MachineType::AnyTagged(), vector, offset);
|
||||
|
||||
// Try to quickly handle the monomorphic case without knowing for sure
|
||||
// if we have a weak cell in feedback. We do know it's safe to look
|
||||
// at WeakCell::kValueOffset.
|
||||
GotoUnless(WordEqual(receiver_map, LoadWeakCellValue(feedback)), if_miss);
|
||||
|
||||
Node* handler = Load(MachineType::AnyTagged(), p->vector,
|
||||
Node* handler = Load(MachineType::AnyTagged(), vector,
|
||||
IntPtrAdd(offset, IntPtrConstant(kPointerSize)));
|
||||
|
||||
var_handler->Bind(handler);
|
||||
@ -3777,9 +3777,8 @@ compiler::Node* CodeStubAssembler::TryMonomorphicCase(
|
||||
}
|
||||
|
||||
void CodeStubAssembler::HandlePolymorphicCase(
|
||||
const LoadICParameters* p, compiler::Node* receiver_map,
|
||||
compiler::Node* feedback, Label* if_handler, Variable* var_handler,
|
||||
Label* if_miss, int unroll_count) {
|
||||
compiler::Node* receiver_map, compiler::Node* feedback, Label* if_handler,
|
||||
Variable* var_handler, Label* if_miss, int unroll_count) {
|
||||
DCHECK_EQ(MachineRepresentation::kTagged, var_handler->rep());
|
||||
|
||||
// Iterate {feedback} array.
|
||||
@ -4312,8 +4311,9 @@ void CodeStubAssembler::LoadIC(const LoadICParameters* p) {
|
||||
Node* receiver_map = LoadReceiverMap(p->receiver);
|
||||
|
||||
// Check monomorphic case.
|
||||
Node* feedback = TryMonomorphicCase(p, receiver_map, &if_handler,
|
||||
&var_handler, &try_polymorphic);
|
||||
Node* feedback =
|
||||
TryMonomorphicCase(p->slot, p->vector, receiver_map, &if_handler,
|
||||
&var_handler, &try_polymorphic);
|
||||
Bind(&if_handler);
|
||||
{
|
||||
HandleLoadICHandlerCase(p, var_handler.value(), &miss);
|
||||
@ -4325,7 +4325,7 @@ void CodeStubAssembler::LoadIC(const LoadICParameters* p) {
|
||||
Comment("LoadIC_try_polymorphic");
|
||||
GotoUnless(WordEqual(LoadMap(feedback), FixedArrayMapConstant()),
|
||||
&try_megamorphic);
|
||||
HandlePolymorphicCase(p, receiver_map, feedback, &if_handler, &var_handler,
|
||||
HandlePolymorphicCase(receiver_map, feedback, &if_handler, &var_handler,
|
||||
&miss, 2);
|
||||
}
|
||||
|
||||
@ -4357,8 +4357,9 @@ void CodeStubAssembler::KeyedLoadIC(const LoadICParameters* p) {
|
||||
Node* receiver_map = LoadReceiverMap(p->receiver);
|
||||
|
||||
// Check monomorphic case.
|
||||
Node* feedback = TryMonomorphicCase(p, receiver_map, &if_handler,
|
||||
&var_handler, &try_polymorphic);
|
||||
Node* feedback =
|
||||
TryMonomorphicCase(p->slot, p->vector, receiver_map, &if_handler,
|
||||
&var_handler, &try_polymorphic);
|
||||
Bind(&if_handler);
|
||||
{
|
||||
HandleLoadICHandlerCase(p, var_handler.value(), &miss, kSupportElements);
|
||||
@ -4370,7 +4371,7 @@ void CodeStubAssembler::KeyedLoadIC(const LoadICParameters* p) {
|
||||
Comment("KeyedLoadIC_try_polymorphic");
|
||||
GotoUnless(WordEqual(LoadMap(feedback), FixedArrayMapConstant()),
|
||||
&try_megamorphic);
|
||||
HandlePolymorphicCase(p, receiver_map, feedback, &if_handler, &var_handler,
|
||||
HandlePolymorphicCase(receiver_map, feedback, &if_handler, &var_handler,
|
||||
&miss, 2);
|
||||
}
|
||||
|
||||
@ -4396,8 +4397,8 @@ void CodeStubAssembler::KeyedLoadIC(const LoadICParameters* p) {
|
||||
p->slot, FAST_HOLEY_ELEMENTS, SMI_PARAMETERS,
|
||||
FixedArray::kHeaderSize + kPointerSize - kHeapObjectTag);
|
||||
Node* array = Load(MachineType::AnyTagged(), p->vector, offset);
|
||||
HandlePolymorphicCase(p, receiver_map, array, &if_handler, &var_handler,
|
||||
&miss, 1);
|
||||
HandlePolymorphicCase(receiver_map, array, &if_handler, &var_handler, &miss,
|
||||
1);
|
||||
}
|
||||
Bind(&miss);
|
||||
{
|
||||
@ -4563,6 +4564,55 @@ void CodeStubAssembler::KeyedLoadICGeneric(const LoadICParameters* p) {
|
||||
}
|
||||
}
|
||||
|
||||
void CodeStubAssembler::StoreIC(const StoreICParameters* p) {
|
||||
Variable var_handler(this, MachineRepresentation::kTagged);
|
||||
// TODO(ishell): defer blocks when it works.
|
||||
Label if_handler(this, &var_handler), try_polymorphic(this),
|
||||
try_megamorphic(this /*, Label::kDeferred*/),
|
||||
miss(this /*, Label::kDeferred*/);
|
||||
|
||||
Node* receiver_map = LoadReceiverMap(p->receiver);
|
||||
|
||||
// Check monomorphic case.
|
||||
Node* feedback =
|
||||
TryMonomorphicCase(p->slot, p->vector, receiver_map, &if_handler,
|
||||
&var_handler, &try_polymorphic);
|
||||
Bind(&if_handler);
|
||||
{
|
||||
Comment("StoreIC_if_handler");
|
||||
StoreWithVectorDescriptor descriptor(isolate());
|
||||
TailCallStub(descriptor, var_handler.value(), p->context, p->receiver,
|
||||
p->name, p->value, p->slot, p->vector);
|
||||
}
|
||||
|
||||
Bind(&try_polymorphic);
|
||||
{
|
||||
// Check polymorphic case.
|
||||
Comment("StoreIC_try_polymorphic");
|
||||
GotoUnless(
|
||||
WordEqual(LoadMap(feedback), LoadRoot(Heap::kFixedArrayMapRootIndex)),
|
||||
&try_megamorphic);
|
||||
HandlePolymorphicCase(receiver_map, feedback, &if_handler, &var_handler,
|
||||
&miss, 2);
|
||||
}
|
||||
|
||||
Bind(&try_megamorphic);
|
||||
{
|
||||
// Check megamorphic case.
|
||||
GotoUnless(
|
||||
WordEqual(feedback, LoadRoot(Heap::kmegamorphic_symbolRootIndex)),
|
||||
&miss);
|
||||
|
||||
TryProbeStubCache(isolate()->store_stub_cache(), p->receiver, p->name,
|
||||
&if_handler, &var_handler, &miss);
|
||||
}
|
||||
Bind(&miss);
|
||||
{
|
||||
TailCallRuntime(Runtime::kStoreIC_Miss, p->context, p->value, p->slot,
|
||||
p->vector, p->receiver, p->name);
|
||||
}
|
||||
}
|
||||
|
||||
void CodeStubAssembler::LoadGlobalIC(const LoadICParameters* p) {
|
||||
Label try_handler(this), miss(this);
|
||||
Node* weak_cell =
|
||||
|
@ -607,7 +607,7 @@ class CodeStubAssembler : public compiler::CodeAssembler {
|
||||
compiler::Node* callable,
|
||||
compiler::Node* object);
|
||||
|
||||
// LoadIC helpers.
|
||||
// Load/StoreIC helpers.
|
||||
struct LoadICParameters {
|
||||
LoadICParameters(compiler::Node* context, compiler::Node* receiver,
|
||||
compiler::Node* name, compiler::Node* slot,
|
||||
@ -625,6 +625,15 @@ class CodeStubAssembler : public compiler::CodeAssembler {
|
||||
compiler::Node* vector;
|
||||
};
|
||||
|
||||
struct StoreICParameters : public LoadICParameters {
|
||||
StoreICParameters(compiler::Node* context, compiler::Node* receiver,
|
||||
compiler::Node* name, compiler::Node* value,
|
||||
compiler::Node* slot, compiler::Node* vector)
|
||||
: LoadICParameters(context, receiver, name, slot, vector),
|
||||
value(value) {}
|
||||
compiler::Node* value;
|
||||
};
|
||||
|
||||
// Load type feedback vector from the stub caller's frame.
|
||||
compiler::Node* LoadTypeFeedbackVectorForStub();
|
||||
|
||||
@ -636,12 +645,12 @@ class CodeStubAssembler : public compiler::CodeAssembler {
|
||||
compiler::Node* LoadReceiverMap(compiler::Node* receiver);
|
||||
|
||||
// Checks monomorphic case. Returns {feedback} entry of the vector.
|
||||
compiler::Node* TryMonomorphicCase(const LoadICParameters* p,
|
||||
compiler::Node* TryMonomorphicCase(compiler::Node* slot,
|
||||
compiler::Node* vector,
|
||||
compiler::Node* receiver_map,
|
||||
Label* if_handler, Variable* var_handler,
|
||||
Label* if_miss);
|
||||
void HandlePolymorphicCase(const LoadICParameters* p,
|
||||
compiler::Node* receiver_map,
|
||||
void HandlePolymorphicCase(compiler::Node* receiver_map,
|
||||
compiler::Node* feedback, Label* if_handler,
|
||||
Variable* var_handler, Label* if_miss,
|
||||
int unroll_count);
|
||||
@ -722,6 +731,7 @@ class CodeStubAssembler : public compiler::CodeAssembler {
|
||||
void LoadGlobalIC(const LoadICParameters* p);
|
||||
void KeyedLoadIC(const LoadICParameters* p);
|
||||
void KeyedLoadICGeneric(const LoadICParameters* p);
|
||||
void StoreIC(const StoreICParameters* p);
|
||||
|
||||
void TransitionElementsKind(compiler::Node* object, compiler::Node* map,
|
||||
ElementsKind from_kind, ElementsKind to_kind,
|
||||
|
@ -498,6 +498,37 @@ void KeyedLoadICTFStub::GenerateAssembly(CodeStubAssembler* assembler) const {
|
||||
assembler->KeyedLoadIC(&p);
|
||||
}
|
||||
|
||||
void StoreICTrampolineTFStub::GenerateAssembly(
|
||||
CodeStubAssembler* assembler) const {
|
||||
typedef compiler::Node Node;
|
||||
|
||||
Node* receiver = assembler->Parameter(Descriptor::kReceiver);
|
||||
Node* name = assembler->Parameter(Descriptor::kName);
|
||||
Node* value = assembler->Parameter(Descriptor::kValue);
|
||||
Node* slot = assembler->Parameter(Descriptor::kSlot);
|
||||
Node* context = assembler->Parameter(Descriptor::kContext);
|
||||
Node* vector = assembler->LoadTypeFeedbackVectorForStub();
|
||||
|
||||
CodeStubAssembler::StoreICParameters p(context, receiver, name, value, slot,
|
||||
vector);
|
||||
assembler->StoreIC(&p);
|
||||
}
|
||||
|
||||
void StoreICTFStub::GenerateAssembly(CodeStubAssembler* assembler) const {
|
||||
typedef compiler::Node Node;
|
||||
|
||||
Node* receiver = assembler->Parameter(Descriptor::kReceiver);
|
||||
Node* name = assembler->Parameter(Descriptor::kName);
|
||||
Node* value = assembler->Parameter(Descriptor::kValue);
|
||||
Node* slot = assembler->Parameter(Descriptor::kSlot);
|
||||
Node* vector = assembler->Parameter(Descriptor::kVector);
|
||||
Node* context = assembler->Parameter(Descriptor::kContext);
|
||||
|
||||
CodeStubAssembler::StoreICParameters p(context, receiver, name, value, slot,
|
||||
vector);
|
||||
assembler->StoreIC(&p);
|
||||
}
|
||||
|
||||
void StoreTransitionStub::GenerateAssembly(CodeStubAssembler* assembler) const {
|
||||
typedef CodeStubAssembler::Label Label;
|
||||
typedef compiler::Node Node;
|
||||
|
@ -164,6 +164,7 @@ class ObjectLiteral;
|
||||
V(StoreFastElement) \
|
||||
V(StoreField) \
|
||||
V(StoreGlobal) \
|
||||
V(StoreICTF) \
|
||||
V(StoreInterceptor) \
|
||||
V(StoreTransition) \
|
||||
V(LoadApiGetter) \
|
||||
@ -176,7 +177,8 @@ class ObjectLiteral;
|
||||
/* only */ \
|
||||
V(LoadICTrampolineTF) \
|
||||
V(LoadGlobalICTrampoline) \
|
||||
V(KeyedLoadICTrampolineTF)
|
||||
V(KeyedLoadICTrampolineTF) \
|
||||
V(StoreICTrampolineTF)
|
||||
|
||||
// List of code stubs only used on ARM 32 bits platforms.
|
||||
#if V8_TARGET_ARCH_ARM
|
||||
@ -2414,15 +2416,34 @@ class StoreICTrampolineStub : public PlatformCodeStub {
|
||||
}
|
||||
|
||||
protected:
|
||||
StoreICState state() const {
|
||||
return StoreICState(static_cast<ExtraICState>(minor_key_));
|
||||
}
|
||||
StoreICState state() const { return StoreICState(GetExtraICState()); }
|
||||
|
||||
private:
|
||||
DEFINE_CALL_INTERFACE_DESCRIPTOR(Store);
|
||||
DEFINE_PLATFORM_CODE_STUB(StoreICTrampoline, PlatformCodeStub);
|
||||
};
|
||||
|
||||
class StoreICTrampolineTFStub : public TurboFanCodeStub {
|
||||
public:
|
||||
StoreICTrampolineTFStub(Isolate* isolate, const StoreICState& state)
|
||||
: TurboFanCodeStub(isolate) {
|
||||
minor_key_ = state.GetExtraICState();
|
||||
}
|
||||
|
||||
void GenerateAssembly(CodeStubAssembler* assembler) const override;
|
||||
|
||||
Code::Kind GetCodeKind() const override { return Code::STORE_IC; }
|
||||
ExtraICState GetExtraICState() const final {
|
||||
return static_cast<ExtraICState>(minor_key_);
|
||||
}
|
||||
|
||||
protected:
|
||||
StoreICState state() const { return StoreICState(GetExtraICState()); }
|
||||
|
||||
DEFINE_CALL_INTERFACE_DESCRIPTOR(Store);
|
||||
DEFINE_CODE_STUB(StoreICTrampolineTF, TurboFanCodeStub);
|
||||
};
|
||||
|
||||
class KeyedStoreICTrampolineStub : public StoreICTrampolineStub {
|
||||
public:
|
||||
KeyedStoreICTrampolineStub(Isolate* isolate, const StoreICState& state)
|
||||
@ -2551,6 +2572,24 @@ class StoreICStub : public PlatformCodeStub {
|
||||
void GenerateImpl(MacroAssembler* masm, bool in_frame);
|
||||
};
|
||||
|
||||
class StoreICTFStub : public TurboFanCodeStub {
|
||||
public:
|
||||
StoreICTFStub(Isolate* isolate, const StoreICState& state)
|
||||
: TurboFanCodeStub(isolate) {
|
||||
minor_key_ = state.GetExtraICState();
|
||||
}
|
||||
|
||||
void GenerateAssembly(CodeStubAssembler* assembler) const override;
|
||||
|
||||
Code::Kind GetCodeKind() const override { return Code::STORE_IC; }
|
||||
ExtraICState GetExtraICState() const final {
|
||||
return static_cast<ExtraICState>(minor_key_);
|
||||
}
|
||||
|
||||
DEFINE_CALL_INTERFACE_DESCRIPTOR(StoreWithVector);
|
||||
DEFINE_CODE_STUB(StoreICTF, TurboFanCodeStub);
|
||||
};
|
||||
|
||||
class KeyedStoreICStub : public PlatformCodeStub {
|
||||
public:
|
||||
KeyedStoreICStub(Isolate* isolate, const StoreICState& state)
|
||||
|
@ -765,6 +765,26 @@ Node* CodeAssembler::TailCallStub(const CallInterfaceDescriptor& descriptor,
|
||||
return raw_assembler_->TailCallN(call_descriptor, target, args);
|
||||
}
|
||||
|
||||
Node* CodeAssembler::TailCallStub(const CallInterfaceDescriptor& descriptor,
|
||||
Node* target, Node* context, Node* arg1,
|
||||
Node* arg2, Node* arg3, Node* arg4,
|
||||
Node* arg5, size_t result_size) {
|
||||
CallDescriptor* call_descriptor = Linkage::GetStubCallDescriptor(
|
||||
isolate(), zone(), descriptor, descriptor.GetStackParameterCount(),
|
||||
CallDescriptor::kSupportsTailCalls, Operator::kNoProperties,
|
||||
MachineType::AnyTagged(), result_size);
|
||||
|
||||
Node** args = zone()->NewArray<Node*>(6);
|
||||
args[0] = arg1;
|
||||
args[1] = arg2;
|
||||
args[2] = arg3;
|
||||
args[3] = arg4;
|
||||
args[4] = arg5;
|
||||
args[5] = context;
|
||||
|
||||
return raw_assembler_->TailCallN(call_descriptor, target, args);
|
||||
}
|
||||
|
||||
Node* CodeAssembler::TailCallStub(const CallInterfaceDescriptor& descriptor,
|
||||
Node* target, Node* context, const Arg& arg1,
|
||||
const Arg& arg2, const Arg& arg3,
|
||||
|
@ -407,6 +407,9 @@ class CodeAssembler {
|
||||
Node* TailCallStub(const CallInterfaceDescriptor& descriptor, Node* target,
|
||||
Node* context, Node* arg1, Node* arg2, Node* arg3,
|
||||
Node* arg4, size_t result_size = 1);
|
||||
Node* TailCallStub(const CallInterfaceDescriptor& descriptor, Node* target,
|
||||
Node* context, Node* arg1, Node* arg2, Node* arg3,
|
||||
Node* arg4, Node* arg5, size_t result_size = 1);
|
||||
|
||||
Node* TailCallStub(const CallInterfaceDescriptor& descriptor, Node* target,
|
||||
Node* context, const Arg& arg1, const Arg& arg2,
|
||||
|
@ -802,6 +802,7 @@ DEFINE_BOOL(use_idle_notification, true,
|
||||
DEFINE_BOOL(use_ic, true, "use inline caching")
|
||||
DEFINE_BOOL(trace_ic, false, "trace inline cache state transitions")
|
||||
DEFINE_BOOL(tf_load_ic_stub, true, "use TF LoadIC stub")
|
||||
DEFINE_BOOL(tf_store_ic_stub, false, "use TF StoreIC stub")
|
||||
|
||||
// macro-assembler-ia32.cc
|
||||
DEFINE_BOOL(native_code_counters, false,
|
||||
|
@ -21782,12 +21782,15 @@ int* LookupCounter(const char* name) {
|
||||
const char* kMegamorphicTestProgram =
|
||||
"function CreateClass(name) {\n"
|
||||
" var src = \n"
|
||||
" ` function ${name}() {};` +\n"
|
||||
" ` function ${name}() { this.a = 0; };` +\n"
|
||||
" ` ${name}.prototype.foo = function() {};` +\n"
|
||||
" ` ${name};\\n`;\n"
|
||||
" return (0, eval)(src);\n"
|
||||
"}\n"
|
||||
"function fooify(obj) { obj.foo(); };\n"
|
||||
"function trigger_ics(obj, v) {\n"
|
||||
" obj.foo();\n"
|
||||
" obj.a = v;\n"
|
||||
"};\n"
|
||||
"var objs = [];\n"
|
||||
"for (var i = 0; i < 50; i++) {\n"
|
||||
" var Class = CreateClass('Class' + i);\n"
|
||||
@ -21796,7 +21799,7 @@ const char* kMegamorphicTestProgram =
|
||||
"}\n"
|
||||
"for (var i = 0; i < 1000; i++) {\n"
|
||||
" for (var obj of objs) {\n"
|
||||
" fooify(obj);\n"
|
||||
" trigger_ics(obj, i);\n"
|
||||
" }\n"
|
||||
"}\n";
|
||||
|
||||
@ -21832,6 +21835,7 @@ void TestStubCache(bool primary) {
|
||||
i::CodeStub::LoadICTF, i::CodeStub::LoadICTrampolineTF,
|
||||
i::CodeStub::KeyedLoadIC, i::CodeStub::KeyedLoadICTrampoline,
|
||||
i::CodeStub::StoreIC, i::CodeStub::StoreICTrampoline,
|
||||
i::CodeStub::StoreICTF, i::CodeStub::StoreICTrampolineTF,
|
||||
i::CodeStub::KeyedStoreIC, i::CodeStub::KeyedStoreICTrampoline,
|
||||
};
|
||||
i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
|
||||
@ -21852,17 +21856,18 @@ void TestStubCache(bool primary) {
|
||||
int updates = updates_counter - initial_updates;
|
||||
const int kClassesCount = 50;
|
||||
const int kIterationsCount = 1000;
|
||||
CHECK_LE(kClassesCount, updates);
|
||||
const int kICKinds = 2; // LoadIC and StoreIC
|
||||
CHECK_LE(kClassesCount * kICKinds, updates);
|
||||
// Check that updates and misses counts are bounded.
|
||||
// If there are too many updates then most likely the stub cache does not
|
||||
// work properly.
|
||||
CHECK_LE(updates, kClassesCount * 2);
|
||||
CHECK_LE(1, misses);
|
||||
CHECK_LE(misses, kClassesCount * 2);
|
||||
CHECK_LE(updates, kClassesCount * 2 * kICKinds);
|
||||
CHECK_LE(kICKinds, misses);
|
||||
CHECK_LE(misses, kClassesCount * 2 * kICKinds);
|
||||
// 2 is for PREMONOMORPHIC and MONOMORPHIC states,
|
||||
// 4 is for POLYMORPHIC states,
|
||||
// and all the others probes are for MEGAMORPHIC state.
|
||||
CHECK_EQ(kIterationsCount * kClassesCount - 2 - 4, probes);
|
||||
CHECK_EQ((kIterationsCount * kClassesCount - 2 - 4) * kICKinds, probes);
|
||||
}
|
||||
isolate->Dispose();
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user