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();
}
bool HasNoTypeInformation() const {
return IsUninitializedField::decode(bit_field_);
return GetInlineCacheState() == UNINITIALIZED;
}
void set_is_uninitialized(bool b) {
bit_field_ = IsUninitializedField::update(bit_field_, b);
InlineCacheState GetInlineCacheState() const {
return InlineCacheStateField::decode(bit_field_);
}
void set_is_string_access(bool b) {
bit_field_ = IsStringAccessField::update(bit_field_, b);
@ -1757,6 +1757,9 @@ class Property FINAL : public Expression {
void set_key_type(IcCheckType 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() {
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)
: Expression(zone, pos),
bit_field_(IsForCallField::encode(false) |
IsUninitializedField::encode(false) |
IsStringAccessField::encode(false)),
IsStringAccessField::encode(false) |
InlineCacheStateField::encode(UNINITIALIZED)),
property_feedback_slot_(FeedbackVectorICSlot::Invalid()),
obj_(obj),
key_(key) {}
@ -1798,9 +1801,9 @@ class Property FINAL : public Expression {
int local_id(int n) const { return base_id() + parent_num_ids() + n; }
class IsForCallField : public BitField8<bool, 0, 1> {};
class IsUninitializedField : public BitField8<bool, 1, 1> {};
class IsStringAccessField : public BitField8<bool, 2, 1> {};
class KeyTypeField : public BitField8<IcCheckType, 3, 1> {};
class IsStringAccessField : public BitField8<bool, 1, 1> {};
class KeyTypeField : public BitField8<IcCheckType, 2, 1> {};
class InlineCacheStateField : public BitField8<InlineCacheState, 3, 4> {};
uint8_t bit_field_;
FeedbackVectorICSlot property_feedback_slot_;
Expression* obj_;

View File

@ -141,8 +141,11 @@ Reduction JSTypeFeedbackSpecializer::ReduceJSLoadNamed(Node* node) {
// TODO(turbofan): type feedback currently requires deoptimization.
if (!FLAG_turbo_deoptimization) return NoChange();
// TODO(turbofan): handle vector-based type feedback.
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());
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);
if (maybe_code->IsCode()) {
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);
if (kind == Code::LOAD_IC) {
LoadICNexus nexus(feedback_vector_, slot);
return nexus.StateFromFeedback() == UNINITIALIZED;
return nexus.StateFromFeedback();
} else if (kind == Code::KEYED_LOAD_IC) {
KeyedLoadICNexus nexus(feedback_vector_, slot);
return nexus.StateFromFeedback() == UNINITIALIZED;
} 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 nexus.StateFromFeedback();
}
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<Context> native_context);
bool LoadIsUninitialized(TypeFeedbackId id);
bool LoadIsUninitialized(FeedbackVectorICSlot slot);
InlineCacheState LoadInlineCacheState(TypeFeedbackId id);
InlineCacheState LoadInlineCacheState(FeedbackVectorICSlot slot);
bool StoreIsUninitialized(TypeFeedbackId id);
bool CallIsUninitialized(FeedbackVectorICSlot slot);
bool CallIsMonomorphic(FeedbackVectorICSlot slot);

View File

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