Pass load ic state through the Oracle.

We'd like to know in optimized code with more precision what feedback
state was achieved for a load.

R=dcarney@chromium.org
BUG=

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

Cr-Commit-Position: refs/heads/master@{#27826}
This commit is contained in:
mvstanton 2015-04-14 18:24:40 -07:00 committed by Commit bot
parent 592c0fe7b6
commit 4598f1d376
5 changed files with 32 additions and 24 deletions

View File

@ -1746,10 +1746,10 @@ class Property FINAL : public Expression {
return !is_for_call() && HasNoTypeInformation(); return !is_for_call() && HasNoTypeInformation();
} }
bool HasNoTypeInformation() const { bool HasNoTypeInformation() const {
return IsUninitializedField::decode(bit_field_); return GetInlineCacheState() == UNINITIALIZED;
} }
void set_is_uninitialized(bool b) { InlineCacheState GetInlineCacheState() const {
bit_field_ = IsUninitializedField::update(bit_field_, b); return InlineCacheStateField::decode(bit_field_);
} }
void set_is_string_access(bool b) { void set_is_string_access(bool b) {
bit_field_ = IsStringAccessField::update(bit_field_, b); bit_field_ = IsStringAccessField::update(bit_field_, b);
@ -1757,6 +1757,9 @@ class Property FINAL : public Expression {
void set_key_type(IcCheckType key_type) { void set_key_type(IcCheckType key_type) {
bit_field_ = KeyTypeField::update(bit_field_, key_type); bit_field_ = KeyTypeField::update(bit_field_, key_type);
} }
void set_inline_cache_state(InlineCacheState state) {
bit_field_ = InlineCacheStateField::update(bit_field_, state);
}
void mark_for_call() { void mark_for_call() {
bit_field_ = IsForCallField::update(bit_field_, true); bit_field_ = IsForCallField::update(bit_field_, true);
} }
@ -1787,8 +1790,8 @@ class Property FINAL : public Expression {
Property(Zone* zone, Expression* obj, Expression* key, int pos) Property(Zone* zone, Expression* obj, Expression* key, int pos)
: Expression(zone, pos), : Expression(zone, pos),
bit_field_(IsForCallField::encode(false) | bit_field_(IsForCallField::encode(false) |
IsUninitializedField::encode(false) | IsStringAccessField::encode(false) |
IsStringAccessField::encode(false)), InlineCacheStateField::encode(UNINITIALIZED)),
property_feedback_slot_(FeedbackVectorICSlot::Invalid()), property_feedback_slot_(FeedbackVectorICSlot::Invalid()),
obj_(obj), obj_(obj),
key_(key) {} key_(key) {}
@ -1798,9 +1801,9 @@ class Property FINAL : public Expression {
int local_id(int n) const { return base_id() + parent_num_ids() + n; } int local_id(int n) const { return base_id() + parent_num_ids() + n; }
class IsForCallField : public BitField8<bool, 0, 1> {}; class IsForCallField : public BitField8<bool, 0, 1> {};
class IsUninitializedField : public BitField8<bool, 1, 1> {}; class IsStringAccessField : public BitField8<bool, 1, 1> {};
class IsStringAccessField : public BitField8<bool, 2, 1> {}; class KeyTypeField : public BitField8<IcCheckType, 2, 1> {};
class KeyTypeField : public BitField8<IcCheckType, 3, 1> {}; class InlineCacheStateField : public BitField8<InlineCacheState, 3, 4> {};
uint8_t bit_field_; uint8_t bit_field_;
FeedbackVectorICSlot property_feedback_slot_; FeedbackVectorICSlot property_feedback_slot_;
Expression* obj_; Expression* obj_;

View File

@ -141,8 +141,11 @@ Reduction JSTypeFeedbackSpecializer::ReduceJSLoadNamed(Node* node) {
// TODO(turbofan): type feedback currently requires deoptimization. // TODO(turbofan): type feedback currently requires deoptimization.
if (!FLAG_turbo_deoptimization) return NoChange(); if (!FLAG_turbo_deoptimization) return NoChange();
// TODO(turbofan): handle vector-based type feedback.
TypeFeedbackId id = js_type_feedback_->find(node); TypeFeedbackId id = js_type_feedback_->find(node);
if (id.IsNone() || oracle()->LoadIsUninitialized(id)) return NoChange(); if (id.IsNone() || oracle()->LoadInlineCacheState(id) == UNINITIALIZED) {
return NoChange();
}
const LoadNamedParameters& p = LoadNamedParametersOf(node->op()); const LoadNamedParameters& p = LoadNamedParametersOf(node->op());
SmallMapList maps; SmallMapList maps;

View File

@ -90,31 +90,33 @@ Handle<Object> TypeFeedbackOracle::GetInfo(FeedbackVectorICSlot slot) {
} }
bool TypeFeedbackOracle::LoadIsUninitialized(TypeFeedbackId id) { InlineCacheState TypeFeedbackOracle::LoadInlineCacheState(TypeFeedbackId id) {
Handle<Object> maybe_code = GetInfo(id); Handle<Object> maybe_code = GetInfo(id);
if (maybe_code->IsCode()) { if (maybe_code->IsCode()) {
Handle<Code> code = Handle<Code>::cast(maybe_code); Handle<Code> code = Handle<Code>::cast(maybe_code);
return code->is_inline_cache_stub() && code->ic_state() == UNINITIALIZED; if (code->is_inline_cache_stub()) return code->ic_state();
} }
return false;
// If we can't find an IC, assume we've seen *something*, but we don't know
// what. PREMONOMORPHIC roughly encodes this meaning.
return PREMONOMORPHIC;
} }
bool TypeFeedbackOracle::LoadIsUninitialized(FeedbackVectorICSlot slot) { InlineCacheState TypeFeedbackOracle::LoadInlineCacheState(
FeedbackVectorICSlot slot) {
Code::Kind kind = feedback_vector_->GetKind(slot); Code::Kind kind = feedback_vector_->GetKind(slot);
if (kind == Code::LOAD_IC) { if (kind == Code::LOAD_IC) {
LoadICNexus nexus(feedback_vector_, slot); LoadICNexus nexus(feedback_vector_, slot);
return nexus.StateFromFeedback() == UNINITIALIZED; return nexus.StateFromFeedback();
} else if (kind == Code::KEYED_LOAD_IC) { } else if (kind == Code::KEYED_LOAD_IC) {
KeyedLoadICNexus nexus(feedback_vector_, slot); KeyedLoadICNexus nexus(feedback_vector_, slot);
return nexus.StateFromFeedback() == UNINITIALIZED; return nexus.StateFromFeedback();
} else if (kind == Code::NUMBER_OF_KINDS) {
// Code::NUMBER_OF_KINDS indicates a slot that was never even compiled
// in full code.
return true;
} }
return false; // If we can't find an IC, assume we've seen *something*, but we don't know
// what. PREMONOMORPHIC roughly encodes this meaning.
return PREMONOMORPHIC;
} }

View File

@ -23,8 +23,8 @@ class TypeFeedbackOracle: public ZoneObject {
Handle<TypeFeedbackVector> feedback_vector, Handle<TypeFeedbackVector> feedback_vector,
Handle<Context> native_context); Handle<Context> native_context);
bool LoadIsUninitialized(TypeFeedbackId id); InlineCacheState LoadInlineCacheState(TypeFeedbackId id);
bool LoadIsUninitialized(FeedbackVectorICSlot slot); InlineCacheState LoadInlineCacheState(FeedbackVectorICSlot slot);
bool StoreIsUninitialized(TypeFeedbackId id); bool StoreIsUninitialized(TypeFeedbackId id);
bool CallIsUninitialized(FeedbackVectorICSlot slot); bool CallIsUninitialized(FeedbackVectorICSlot slot);
bool CallIsMonomorphic(FeedbackVectorICSlot slot); bool CallIsMonomorphic(FeedbackVectorICSlot slot);

View File

@ -495,10 +495,10 @@ void AstTyper::VisitProperty(Property* expr) {
TypeFeedbackId id(TypeFeedbackId::None()); TypeFeedbackId id(TypeFeedbackId::None());
if (FLAG_vector_ics) { if (FLAG_vector_ics) {
slot = expr->PropertyFeedbackSlot(); slot = expr->PropertyFeedbackSlot();
expr->set_is_uninitialized(oracle()->LoadIsUninitialized(slot)); expr->set_inline_cache_state(oracle()->LoadInlineCacheState(slot));
} else { } else {
id = expr->PropertyFeedbackId(); id = expr->PropertyFeedbackId();
expr->set_is_uninitialized(oracle()->LoadIsUninitialized(id)); expr->set_inline_cache_state(oracle()->LoadInlineCacheState(id));
} }
if (!expr->IsUninitialized()) { if (!expr->IsUninitialized()) {