Revision: 22505
Author: yang...@chromium.org
Date: Mon Jul 21 13:10:14 2014 UTC
Log: Store both major and minor key on code stubs.
R=jkumme...@chromium.org
Review URL: https://codereview.chromium.org/409613002
http://code.google.com/p/v8/source/detail?r=22505
Modified:
/branches/bleeding_edge/src/code-stubs.cc
/branches/bleeding_edge/src/code-stubs.h
/branches/bleeding_edge/src/debug.cc
/branches/bleeding_edge/src/deoptimizer.cc
/branches/bleeding_edge/src/heap-snapshot-generator.cc
/branches/bleeding_edge/src/ic.cc
/branches/bleeding_edge/src/ic.h
/branches/bleeding_edge/src/liveedit.cc
/branches/bleeding_edge/src/objects-debug.cc
/branches/bleeding_edge/src/objects-inl.h
/branches/bleeding_edge/src/objects.cc
/branches/bleeding_edge/src/objects.h
/branches/bleeding_edge/src/stub-cache.cc
/branches/bleeding_edge/src/type-info.cc
=======================================
--- /branches/bleeding_edge/src/code-stubs.cc Thu Jul 17 11:50:04 2014 UTC
+++ /branches/bleeding_edge/src/code-stubs.cc Mon Jul 21 13:10:14 2014 UTC
@@ -189,7 +189,7 @@
HandleScope scope(isolate());
Handle<Code> new_object = GenerateCode();
- new_object->set_major_key(MajorKey());
+ new_object->set_stub_key(GetKey());
FinishCode(new_object);
RecordCodeGeneration(new_object);
@@ -371,8 +371,8 @@
*code_out = Code::cast(*probe);
#ifdef DEBUG
Token::Value cached_op;
- ICCompareStub::DecodeMinorKey((*code_out)->stub_info(), NULL, NULL,
NULL,
- &cached_op);
+ ICCompareStub::DecodeKey((*code_out)->stub_key(), NULL, NULL, NULL,
+ &cached_op);
ASSERT(op_ == cached_op);
#endif
return true;
@@ -389,11 +389,11 @@
}
-void ICCompareStub::DecodeMinorKey(int minor_key,
- CompareIC::State* left_state,
- CompareIC::State* right_state,
- CompareIC::State* handler_state,
- Token::Value* op) {
+void ICCompareStub::DecodeKey(uint32_t stub_key, CompareIC::State*
left_state,
+ CompareIC::State* right_state,
+ CompareIC::State* handler_state,
+ Token::Value* op) {
+ int minor_key = MinorKeyFromKey(stub_key);
if (left_state) {
*left_state =
static_cast<CompareIC::State>(LeftStateField::decode(minor_key));
=======================================
--- /branches/bleeding_edge/src/code-stubs.h Thu Jul 17 11:50:04 2014 UTC
+++ /branches/bleeding_edge/src/code-stubs.h Mon Jul 21 13:10:14 2014 UTC
@@ -154,8 +154,10 @@
// Gets the major key from a code object that is a code stub or binary
op IC.
static Major GetMajorKey(Code* code_stub) {
- return static_cast<Major>(code_stub->major_key());
+ return MajorKeyFromKey(code_stub->stub_key());
}
+
+ static uint32_t NoCacheKey() { return MajorKeyBits::encode(NoCache); }
static const char* MajorName(Major major_key, bool allow_unknown_keys);
@@ -206,6 +208,12 @@
virtual void PrintName(OStream& os) const; // NOLINT
virtual void PrintBaseName(OStream& os) const; // NOLINT
virtual void PrintState(OStream& os) const { ; } // NOLINT
+
+ // Computes the key based on major and minor.
+ uint32_t GetKey() {
+ ASSERT(static_cast<int>(MajorKey()) < NUMBER_OF_IDS);
+ return MinorKeyBits::encode(MinorKey()) |
MajorKeyBits::encode(MajorKey());
+ }
private:
// Perform bookkeeping required after code generation when stub code is
@@ -234,13 +242,6 @@
// If a stub uses a special cache override this.
virtual bool UseSpecialCache() { return false; }
-
- // Computes the key based on major and minor.
- uint32_t GetKey() {
- ASSERT(static_cast<int>(MajorKey()) < NUMBER_OF_IDS);
- return MinorKeyBits::encode(MinorKey()) |
- MajorKeyBits::encode(MajorKey());
- }
STATIC_ASSERT(NUMBER_OF_IDS < (1 << kStubMajorKeyBits));
class MajorKeyBits: public BitField<uint32_t, 0, kStubMajorKeyBits> {};
@@ -830,15 +831,10 @@
virtual Code::Kind GetCodeKind() const { return kind_; }
virtual InlineCacheState GetICState() { return MONOMORPHIC; }
- bool Describes(Code* code) {
- return GetMajorKey(code) == MajorKey() && code->stub_info() ==
MinorKey();
- }
+ bool Describes(Code* code) { return code->stub_key() == GetKey(); }
protected:
class KindBits: public BitField<Code::Kind, 0, 4> {};
- virtual void FinishCode(Handle<Code> code) {
- code->set_stub_info(MinorKey());
- }
Code::Kind kind() const { return kind_; }
virtual int MinorKey() const { return KindBits::encode(kind_); }
@@ -1366,11 +1362,9 @@
void set_known_map(Handle<Map> map) { known_map_ = map; }
- static void DecodeMinorKey(int minor_key,
- CompareIC::State* left_state,
- CompareIC::State* right_state,
- CompareIC::State* handler_state,
- Token::Value* op);
+ static void DecodeKey(uint32_t stub_key, CompareIC::State* left_state,
+ CompareIC::State* right_state,
+ CompareIC::State* handler_state, Token::Value* op);
virtual InlineCacheState GetICState();
@@ -1380,10 +1374,6 @@
class RightStateField: public BitField<int, 7, 4> { };
class HandlerStateField: public BitField<int, 11, 4> { };
- virtual void FinishCode(Handle<Code> code) {
- code->set_stub_info(MinorKey());
- }
-
virtual CodeStub::Major MajorKey() const { return CompareIC; }
virtual int MinorKey() const;
=======================================
--- /branches/bleeding_edge/src/debug.cc Fri Jul 18 13:47:25 2014 UTC
+++ /branches/bleeding_edge/src/debug.cc Mon Jul 21 13:10:14 2014 UTC
@@ -373,7 +373,7 @@
Address target = original_rinfo()->target_address();
Handle<Code> target_code(Code::GetCodeFromTargetAddress(target));
if (target_code->kind() == Code::STUB) {
- return target_code->major_key() == CodeStub::CallFunction;
+ return CodeStub::GetMajorKey(*target_code) == CodeStub::CallFunction;
}
return target_code->is_call_stub();
}
@@ -398,7 +398,8 @@
}
bool is_call_function_stub =
(maybe_call_function_stub->kind() == Code::STUB &&
- maybe_call_function_stub->major_key() == CodeStub::CallFunction);
+ CodeStub::GetMajorKey(*maybe_call_function_stub) ==
+ CodeStub::CallFunction);
// Step in through construct call requires no changes to the running
code.
// Step in through getters/setters should already be prepared as well
@@ -475,7 +476,7 @@
}
}
if (code->kind() == Code::STUB) {
- ASSERT(code->major_key() == CodeStub::CallFunction);
+ ASSERT(CodeStub::GetMajorKey(*code) == CodeStub::CallFunction);
return isolate->builtins()->CallFunctionStub_DebugBreak();
}
@@ -1419,7 +1420,8 @@
Code::GetCodeFromTargetAddress(original_target);
}
if ((maybe_call_function_stub->kind() == Code::STUB &&
- maybe_call_function_stub->major_key() ==
CodeStub::CallFunction) ||
+ CodeStub::GetMajorKey(maybe_call_function_stub) ==
+ CodeStub::CallFunction) ||
maybe_call_function_stub->kind() == Code::CALL_IC) {
// Save reference to the code as we may need it to find out
arguments
// count for 'step in' later.
@@ -1499,7 +1501,8 @@
CodeStub::MinorKeyFromKey(key));
ASSERT(is_call_ic ||
- call_function_stub->major_key() ==
CodeStub::MajorKeyFromKey(key));
+ CodeStub::GetMajorKey(*call_function_stub) ==
+ CodeStub::MajorKeyFromKey(key));
// Find target function on the expression stack.
// Expression stack looks like this (top to bottom):
=======================================
--- /branches/bleeding_edge/src/deoptimizer.cc Thu Jul 17 11:50:04 2014 UTC
+++ /branches/bleeding_edge/src/deoptimizer.cc Mon Jul 21 13:10:14 2014 UTC
@@ -1549,7 +1549,7 @@
//
CHECK(compiled_code_->is_hydrogen_stub());
- int major_key = compiled_code_->major_key();
+ int major_key = CodeStub::GetMajorKey(compiled_code_);
CodeStubInterfaceDescriptor* descriptor =
isolate_->code_stub_interface_descriptor(major_key);
=======================================
--- /branches/bleeding_edge/src/heap-snapshot-generator.cc Fri Jul 18
11:04:20 2014 UTC
+++ /branches/bleeding_edge/src/heap-snapshot-generator.cc Mon Jul 21
13:10:14 2014 UTC
@@ -1499,8 +1499,8 @@
void V8HeapExplorer::TagCodeObject(Code* code) {
if (code->kind() == Code::STUB) {
TagObject(code, names_->GetFormatted(
- "(%s code)", CodeStub::MajorName(
- static_cast<CodeStub::Major>(code->major_key()), true)));
+ "(%s code)", CodeStub::MajorName(
+ CodeStub::GetMajorKey(code),
true)));
}
}
=======================================
--- /branches/bleeding_edge/src/ic.cc Fri Jul 18 13:50:21 2014 UTC
+++ /branches/bleeding_edge/src/ic.cc Mon Jul 21 13:10:14 2014 UTC
@@ -514,11 +514,10 @@
Address address,
Code* target,
ConstantPoolArray* constant_pool) {
- ASSERT(target->major_key() == CodeStub::CompareIC);
+ ASSERT(CodeStub::GetMajorKey(target) == CodeStub::CompareIC);
CompareIC::State handler_state;
Token::Value op;
- ICCompareStub::DecodeMinorKey(target->stub_info(), NULL, NULL,
- &handler_state, &op);
+ ICCompareStub::DecodeKey(target->stub_key(), NULL, NULL, &handler_state,
&op);
// Only clear CompareICs that can retain objects.
if (handler_state != KNOWN_OBJECT) return;
SetTargetAtAddress(address, GetRawUninitialized(isolate, op),
constant_pool);
@@ -2756,15 +2755,12 @@
}
-void CompareIC::StubInfoToType(int stub_minor_key,
- Type** left_type,
- Type** right_type,
- Type** overall_type,
- Handle<Map> map,
- Zone* zone) {
+void CompareIC::StubInfoToType(uint32_t stub_key, Type** left_type,
+ Type** right_type, Type** overall_type,
+ Handle<Map> map, Zone* zone) {
State left_state, right_state, handler_state;
- ICCompareStub::DecodeMinorKey(stub_minor_key, &left_state, &right_state,
- &handler_state, NULL);
+ ICCompareStub::DecodeKey(stub_key, &left_state, &right_state,
&handler_state,
+ NULL);
*left_type = StateToType(zone, left_state);
*right_type = StateToType(zone, right_state);
*overall_type = StateToType(zone, handler_state, map);
@@ -2880,8 +2876,8 @@
Code* CompareIC::UpdateCaches(Handle<Object> x, Handle<Object> y) {
HandleScope scope(isolate());
State previous_left, previous_right, previous_state;
- ICCompareStub::DecodeMinorKey(target()->stub_info(), &previous_left,
- &previous_right, &previous_state, NULL);
+ ICCompareStub::DecodeKey(target()->stub_key(), &previous_left,
+ &previous_right, &previous_state, NULL);
State new_left = NewInputState(previous_left, x);
State new_right = NewInputState(previous_right, y);
State state = TargetState(previous_state, previous_left, previous_right,
=======================================
--- /branches/bleeding_edge/src/ic.h Mon Jul 21 11:19:56 2014 UTC
+++ /branches/bleeding_edge/src/ic.h Mon Jul 21 13:10:14 2014 UTC
@@ -951,12 +951,9 @@
State state,
Handle<Map> map = Handle<Map>());
- static void StubInfoToType(int stub_minor_key,
- Type** left_type,
- Type** right_type,
- Type** overall_type,
- Handle<Map> map,
- Zone* zone);
+ static void StubInfoToType(uint32_t stub_key, Type** left_type,
+ Type** right_type, Type** overall_type,
+ Handle<Map> map, Zone* zone);
CompareIC(Isolate* isolate, Token::Value op)
: IC(EXTRA_CALL_FRAME, isolate), op_(op) { }
=======================================
--- /branches/bleeding_edge/src/liveedit.cc Mon Jul 14 14:52:24 2014 UTC
+++ /branches/bleeding_edge/src/liveedit.cc Mon Jul 21 13:10:14 2014 UTC
@@ -1638,7 +1638,7 @@
isolate->builtins()->builtin(Builtins::kReturn_DebugBreak)) {
*mode = LiveEdit::FRAME_DROPPED_IN_RETURN_CALL;
} else if (pre_top_frame_code->kind() == Code::STUB &&
- pre_top_frame_code->major_key() == CodeStub::CEntry) {
+ CodeStub::GetMajorKey(pre_top_frame_code) ==
CodeStub::CEntry) {
// Entry from our unit tests on 'debugger' statement.
// It's fine, we support this case.
*mode = LiveEdit::FRAME_DROPPED_IN_DIRECT_CALL;
=======================================
--- /branches/bleeding_edge/src/objects-debug.cc Mon Jul 7 09:57:29 2014
UTC
+++ /branches/bleeding_edge/src/objects-debug.cc Mon Jul 21 13:10:14 2014
UTC
@@ -639,6 +639,8 @@
last_gc_pc = it.rinfo()->pc();
}
}
+ CHECK(raw_type_feedback_info()->IsUndefined() ||
+ raw_type_feedback_info()->IsSmi() == IsCodeStubOrIC());
}
=======================================
--- /branches/bleeding_edge/src/objects-inl.h Mon Jul 21 09:58:01 2014 UTC
+++ /branches/bleeding_edge/src/objects-inl.h Mon Jul 21 13:10:14 2014 UTC
@@ -4619,6 +4619,15 @@
Code::Kind Code::kind() {
return ExtractKindFromFlags(flags());
}
+
+
+bool Code::IsCodeStubOrIC() {
+ return kind() == STUB || kind() == HANDLER || kind() == LOAD_IC ||
+ kind() == KEYED_LOAD_IC || kind() == CALL_IC || kind() ==
STORE_IC ||
+ kind() == KEYED_STORE_IC || kind() == BINARY_OP_IC ||
+ kind() == COMPARE_IC || kind() == COMPARE_NIL_IC ||
+ kind() == TO_BOOLEAN_IC;
+}
InlineCacheState Code::ic_state() {
@@ -4671,37 +4680,6 @@
int updated = IsCrankshaftedField::update(previous, value);
WRITE_UINT32_FIELD(this, kKindSpecificFlags2Offset, updated);
}
-
-
-int Code::major_key() {
- ASSERT(has_major_key());
- return StubMajorKeyField::decode(
- READ_UINT32_FIELD(this, kKindSpecificFlags2Offset));
-}
-
-
-void Code::set_major_key(int major) {
- ASSERT(has_major_key());
- ASSERT(0 <= major && major < 256);
- int previous = READ_UINT32_FIELD(this, kKindSpecificFlags2Offset);
- int updated = StubMajorKeyField::update(previous, major);
- WRITE_UINT32_FIELD(this, kKindSpecificFlags2Offset, updated);
-}
-
-
-bool Code::has_major_key() {
- return kind() == STUB ||
- kind() == HANDLER ||
- kind() == BINARY_OP_IC ||
- kind() == COMPARE_IC ||
- kind() == COMPARE_NIL_IC ||
- kind() == LOAD_IC ||
- kind() == KEYED_LOAD_IC ||
- kind() == STORE_IC ||
- kind() == CALL_IC ||
- kind() == KEYED_STORE_IC ||
- kind() == TO_BOOLEAN_IC;
-}
bool Code::optimizable() {
@@ -6130,7 +6108,7 @@
WRITE_FIELD(this, kHandlerTableOffset, NULL);
WRITE_FIELD(this, kDeoptimizationDataOffset, NULL);
WRITE_FIELD(this, kConstantPoolOffset, NULL);
- // Do not wipe out e.g. a minor key.
+ // Do not wipe out major/minor keys on a code stub or IC
if (!READ_FIELD(this, kTypeFeedbackInfoOffset)->IsSmi()) {
WRITE_FIELD(this, kTypeFeedbackInfoOffset, NULL);
}
@@ -6151,24 +6129,15 @@
}
-int Code::stub_info() {
- ASSERT(kind() == COMPARE_IC || kind() == COMPARE_NIL_IC ||
- kind() == BINARY_OP_IC || kind() == LOAD_IC || kind() == CALL_IC);
- return Smi::cast(raw_type_feedback_info())->value();
+uint32_t Code::stub_key() {
+ ASSERT(IsCodeStubOrIC());
+ return Smi::cast(raw_type_feedback_info())->value() - Smi::kMinValue;
}
-void Code::set_stub_info(int value) {
- ASSERT(kind() == COMPARE_IC ||
- kind() == COMPARE_NIL_IC ||
- kind() == BINARY_OP_IC ||
- kind() == STUB ||
- kind() == LOAD_IC ||
- kind() == CALL_IC ||
- kind() == KEYED_LOAD_IC ||
- kind() == STORE_IC ||
- kind() == KEYED_STORE_IC);
- set_raw_type_feedback_info(Smi::FromInt(value));
+void Code::set_stub_key(uint32_t key) {
+ ASSERT(IsCodeStubOrIC());
+ set_raw_type_feedback_info(Smi::FromInt(key + Smi::kMinValue));
}
=======================================
--- /branches/bleeding_edge/src/objects.cc Sat Jul 19 12:00:20 2014 UTC
+++ /branches/bleeding_edge/src/objects.cc Mon Jul 21 13:10:14 2014 UTC
@@ -11438,7 +11438,7 @@
void Code::Disassemble(const char* name, OStream& os) { // NOLINT
os << "kind = " << Kind2String(kind()) << "\n";
- if (has_major_key()) {
+ if (IsCodeStubOrIC()) {
const char* n = CodeStub::MajorName(CodeStub::GetMajorKey(this), true);
os << "major_key = " << (n == NULL ? "null" : n) << "\n";
}
@@ -11449,11 +11449,11 @@
os << "type = " << StubType2String(type()) << "\n";
}
if (is_compare_ic_stub()) {
- ASSERT(major_key() == CodeStub::CompareIC);
+ ASSERT(CodeStub::GetMajorKey(this) == CodeStub::CompareIC);
CompareIC::State left_state, right_state, handler_state;
Token::Value op;
- ICCompareStub::DecodeMinorKey(stub_info(), &left_state, &right_state,
- &handler_state, &op);
+ ICCompareStub::DecodeKey(stub_key(), &left_state, &right_state,
+ &handler_state, &op);
os << "compare_state = " << CompareIC::GetStateName(left_state)
<< "*"
<< CompareIC::GetStateName(right_state) << " -> "
<< CompareIC::GetStateName(handler_state) << "\n";
=======================================
--- /branches/bleeding_edge/src/objects.h Mon Jul 21 09:58:01 2014 UTC
+++ /branches/bleeding_edge/src/objects.h Mon Jul 21 13:10:14 2014 UTC
@@ -5460,13 +5460,13 @@
// [raw_type_feedback_info]: This field stores various things, depending
on
// the kind of the code object.
// FUNCTION => type feedback information.
- // STUB => various things, e.g. a SMI
+ // STUB and ICs => major/minor key as Smi.
DECL_ACCESSORS(raw_type_feedback_info, Object)
inline Object* type_feedback_info();
inline void set_type_feedback_info(
Object* value, WriteBarrierMode mode = UPDATE_WRITE_BARRIER);
- inline int stub_info();
- inline void set_stub_info(int info);
+ inline uint32_t stub_key();
+ inline void set_stub_key(uint32_t key);
// [next_code_link]: Link for lists of optimized or deoptimized code.
// Note that storage for this field is overlapped with typefeedback_info.
@@ -5529,15 +5529,12 @@
k == KEYED_STORE_IC || k == COMPARE_NIL_IC) &&
ic_state() == MONOMORPHIC;
}
+
+ inline bool IsCodeStubOrIC();
inline void set_raw_kind_specific_flags1(int value);
inline void set_raw_kind_specific_flags2(int value);
- // [major_key]: For kind STUB or BINARY_OP_IC, the major key.
- inline int major_key();
- inline void set_major_key(int value);
- inline bool has_major_key();
-
// For kind STUB or ICs, tells whether or not a code object was
generated by
// the optimizing compiler (but it may not be an optimized function).
bool is_crankshafted();
@@ -5808,6 +5805,7 @@
static const int kHandlerTableOffset = kRelocationInfoOffset +
kPointerSize;
static const int kDeoptimizationDataOffset =
kHandlerTableOffset + kPointerSize;
+ // For FUNCTION kind, we store the type feedback info here.
static const int kTypeFeedbackInfoOffset =
kDeoptimizationDataOffset + kPointerSize;
static const int kNextCodeLinkOffset = kTypeFeedbackInfoOffset +
kPointerSize;
@@ -5890,22 +5888,16 @@
kIsCrankshaftedBit, 1> {}; // NOLINT
// KindSpecificFlags2 layout (STUB and OPTIMIZED_FUNCTION)
- static const int kStubMajorKeyFirstBit = kIsCrankshaftedBit + 1;
- static const int kSafepointTableOffsetFirstBit =
- kStubMajorKeyFirstBit + kStubMajorKeyBits;
+ static const int kSafepointTableOffsetFirstBit = kIsCrankshaftedBit + 1;
static const int kSafepointTableOffsetBitCount = 24;
- STATIC_ASSERT(kStubMajorKeyFirstBit + kStubMajorKeyBits <= 32);
STATIC_ASSERT(kSafepointTableOffsetFirstBit +
kSafepointTableOffsetBitCount <= 32);
- STATIC_ASSERT(1 + kStubMajorKeyBits +
- kSafepointTableOffsetBitCount <= 32);
+ STATIC_ASSERT(1 + kSafepointTableOffsetBitCount <= 32);
class SafepointTableOffsetField: public BitField<int,
kSafepointTableOffsetFirstBit,
kSafepointTableOffsetBitCount> {}; // NOLINT
- class StubMajorKeyField: public BitField<int,
- kStubMajorKeyFirstBit, kStubMajorKeyBits> {}; // NOLINT
// KindSpecificFlags2 layout (FUNCTION)
class BackEdgeTableOffsetField: public BitField<int,
=======================================
--- /branches/bleeding_edge/src/stub-cache.cc Fri Jul 18 13:50:21 2014 UTC
+++ /branches/bleeding_edge/src/stub-cache.cc Mon Jul 21 13:10:14 2014 UTC
@@ -704,9 +704,7 @@
CodeDesc desc;
masm_.GetCode(&desc);
Handle<Code> code = factory()->NewCode(desc, flags, masm_.CodeObject());
- if (code->has_major_key()) {
- code->set_major_key(CodeStub::NoCache);
- }
+ if (code->IsCodeStubOrIC()) code->set_stub_key(CodeStub::NoCacheKey());
#ifdef ENABLE_DISASSEMBLER
if (FLAG_print_code_stubs) {
OFStream os(stdout);
=======================================
--- /branches/bleeding_edge/src/type-info.cc Tue Jun 3 08:12:43 2014 UTC
+++ /branches/bleeding_edge/src/type-info.cc Mon Jul 21 13:10:14 2014 UTC
@@ -207,9 +207,8 @@
}
if (code->is_compare_ic_stub()) {
- int stub_minor_key = code->stub_info();
- CompareIC::StubInfoToType(
- stub_minor_key, left_type, right_type, combined_type, map, zone());
+ CompareIC::StubInfoToType(code->stub_key(), left_type, right_type,
+ combined_type, map, zone());
} else if (code->is_compare_nil_ic_stub()) {
CompareNilICStub stub(isolate(), code->extra_ic_state());
*combined_type = stub.GetType(zone(), map);
--
--
v8-dev mailing list
v8-dev@googlegroups.com
http://groups.google.com/group/v8-dev
---
You received this message because you are subscribed to the Google Groups "v8-dev" group.
To unsubscribe from this group and stop receiving emails from it, send an email
to v8-dev+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.