Commit bf3d84e3 authored by rossberg@chromium.org's avatar rossberg@chromium.org

Move more logic from AST to oracle, pt 3

Also eliminates remaining dependencies of type-info on AST.

R=jkummerow@chromium.org
BUG=

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

git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@18194 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
parent 620c985a
...@@ -580,35 +580,6 @@ void Expression::RecordToBooleanTypeFeedback(TypeFeedbackOracle* oracle) { ...@@ -580,35 +580,6 @@ void Expression::RecordToBooleanTypeFeedback(TypeFeedbackOracle* oracle) {
} }
void Assignment::RecordTypeFeedback(TypeFeedbackOracle* oracle,
Zone* zone) {
Property* prop = target()->AsProperty();
ASSERT(prop != NULL);
TypeFeedbackId id = AssignmentFeedbackId();
is_uninitialized_ = oracle->StoreIsUninitialized(id);
if (is_uninitialized_) return;
is_pre_monomorphic_ = oracle->StoreIsPreMonomorphic(id);
is_monomorphic_ = oracle->StoreIsMonomorphicNormal(id);
ASSERT(!is_pre_monomorphic_ || !is_monomorphic_);
receiver_types_.Clear();
if (prop->key()->IsPropertyName()) {
Literal* lit_key = prop->key()->AsLiteral();
ASSERT(lit_key != NULL && lit_key->value()->IsString());
Handle<String> name = Handle<String>::cast(lit_key->value());
oracle->StoreReceiverTypes(this, name, &receiver_types_);
} else if (is_monomorphic_) {
// Record receiver type for monomorphic keyed stores.
receiver_types_.Add(oracle->StoreMonomorphicReceiverType(id), zone);
store_mode_ = oracle->GetStoreMode(id);
} else if (oracle->StoreIsKeyedPolymorphic(id)) {
receiver_types_.Reserve(kMaxKeyedPolymorphism, zone);
oracle->CollectKeyedReceiverTypes(id, &receiver_types_);
store_mode_ = oracle->GetStoreMode(id);
}
}
bool Call::ComputeTarget(Handle<Map> type, Handle<String> name) { bool Call::ComputeTarget(Handle<Map> type, Handle<String> name) {
// If there is an interceptor, we can't compute the target for a direct call. // If there is an interceptor, we can't compute the target for a direct call.
if (type->has_named_interceptor()) return false; if (type->has_named_interceptor()) return false;
...@@ -711,20 +682,21 @@ Handle<JSObject> Call::GetPrototypeForPrimitiveCheck( ...@@ -711,20 +682,21 @@ Handle<JSObject> Call::GetPrototypeForPrimitiveCheck(
void Call::RecordTypeFeedback(TypeFeedbackOracle* oracle, void Call::RecordTypeFeedback(TypeFeedbackOracle* oracle,
CallKind call_kind) { CallKind call_kind) {
is_monomorphic_ = oracle->CallIsMonomorphic(this); is_monomorphic_ = oracle->CallIsMonomorphic(CallFeedbackId());
Property* property = expression()->AsProperty(); Property* property = expression()->AsProperty();
if (property == NULL) { if (property == NULL) {
// Function call. Specialize for monomorphic calls. // Function call. Specialize for monomorphic calls.
if (is_monomorphic_) target_ = oracle->GetCallTarget(this); if (is_monomorphic_) target_ = oracle->GetCallTarget(CallFeedbackId());
} else if (property->key()->IsPropertyName()) { } else if (property->key()->IsPropertyName()) {
// Method call. Specialize for the receiver types seen at runtime. // Method call. Specialize for the receiver types seen at runtime.
Literal* key = property->key()->AsLiteral(); Literal* key = property->key()->AsLiteral();
ASSERT(key != NULL && key->value()->IsString()); ASSERT(key != NULL && key->value()->IsString());
Handle<String> name = Handle<String>::cast(key->value()); Handle<String> name = Handle<String>::cast(key->value());
check_type_ = oracle->GetCallCheckType(this); check_type_ = oracle->GetCallCheckType(CallFeedbackId());
receiver_types_.Clear(); receiver_types_.Clear();
if (check_type_ == RECEIVER_MAP_CHECK) { if (check_type_ == RECEIVER_MAP_CHECK) {
oracle->CallReceiverTypes(this, name, call_kind, &receiver_types_); oracle->CallReceiverTypes(CallFeedbackId(),
name, arguments()->length(), call_kind, &receiver_types_);
is_monomorphic_ = is_monomorphic_ && receiver_types_.length() > 0; is_monomorphic_ = is_monomorphic_ && receiver_types_.length() > 0;
} else { } else {
holder_ = GetPrototypeForPrimitiveCheck(check_type_, oracle->isolate()); holder_ = GetPrototypeForPrimitiveCheck(check_type_, oracle->isolate());
...@@ -745,17 +717,19 @@ void Call::RecordTypeFeedback(TypeFeedbackOracle* oracle, ...@@ -745,17 +717,19 @@ void Call::RecordTypeFeedback(TypeFeedbackOracle* oracle,
} }
} else { } else {
if (is_monomorphic_) { if (is_monomorphic_) {
keyed_array_call_is_holey_ = oracle->KeyedArrayCallIsHoley(this); keyed_array_call_is_holey_ =
oracle->KeyedArrayCallIsHoley(CallFeedbackId());
} }
} }
} }
void CallNew::RecordTypeFeedback(TypeFeedbackOracle* oracle) { void CallNew::RecordTypeFeedback(TypeFeedbackOracle* oracle) {
allocation_info_cell_ = oracle->GetCallNewAllocationInfoCell(this); allocation_info_cell_ =
is_monomorphic_ = oracle->CallNewIsMonomorphic(this); oracle->GetCallNewAllocationInfoCell(CallNewFeedbackId());
is_monomorphic_ = oracle->CallNewIsMonomorphic(CallNewFeedbackId());
if (is_monomorphic_) { if (is_monomorphic_) {
target_ = oracle->GetCallNewTarget(this); target_ = oracle->GetCallNewTarget(CallNewFeedbackId());
Object* value = allocation_info_cell_->value(); Object* value = allocation_info_cell_->value();
ASSERT(!value->IsTheHole()); ASSERT(!value->IsTheHole());
if (value->IsAllocationSite()) { if (value->IsAllocationSite()) {
...@@ -767,9 +741,9 @@ void CallNew::RecordTypeFeedback(TypeFeedbackOracle* oracle) { ...@@ -767,9 +741,9 @@ void CallNew::RecordTypeFeedback(TypeFeedbackOracle* oracle) {
void ObjectLiteral::Property::RecordTypeFeedback(TypeFeedbackOracle* oracle) { void ObjectLiteral::Property::RecordTypeFeedback(TypeFeedbackOracle* oracle) {
receiver_type_ = oracle->ObjectLiteralStoreIsMonomorphic(this) TypeFeedbackId id = key()->LiteralFeedbackId();
? oracle->GetObjectLiteralStoreMap(this) receiver_type_ = oracle->ObjectLiteralStoreIsMonomorphic(id)
: Handle<Map>::null(); ? oracle->GetObjectLiteralStoreMap(id) : Handle<Map>::null();
} }
......
...@@ -2142,7 +2142,6 @@ class Assignment V8_FINAL : public Expression { ...@@ -2142,7 +2142,6 @@ class Assignment V8_FINAL : public Expression {
// Type feedback information. // Type feedback information.
TypeFeedbackId AssignmentFeedbackId() { return reuse(id()); } TypeFeedbackId AssignmentFeedbackId() { return reuse(id()); }
void RecordTypeFeedback(TypeFeedbackOracle* oracle, Zone* zone);
virtual bool IsMonomorphic() V8_OVERRIDE { return is_monomorphic_; } virtual bool IsMonomorphic() V8_OVERRIDE { return is_monomorphic_; }
bool IsUninitialized() { return is_uninitialized_; } bool IsUninitialized() { return is_uninitialized_; }
bool IsPreMonomorphic() { return is_pre_monomorphic_; } bool IsPreMonomorphic() { return is_pre_monomorphic_; }
...@@ -2155,6 +2154,10 @@ class Assignment V8_FINAL : public Expression { ...@@ -2155,6 +2154,10 @@ class Assignment V8_FINAL : public Expression {
virtual KeyedAccessStoreMode GetStoreMode() V8_OVERRIDE { virtual KeyedAccessStoreMode GetStoreMode() V8_OVERRIDE {
return store_mode_; return store_mode_;
} }
void set_is_uninitialized(bool b) { is_uninitialized_ = b; }
void set_is_monomorphic(bool b) { is_monomorphic_ = b; }
void set_is_pre_monomorphic(bool b) { is_pre_monomorphic_ = b; }
void set_store_mode(KeyedAccessStoreMode mode) { store_mode_ = mode; }
protected: protected:
Assignment(Isolate* isolate, Assignment(Isolate* isolate,
......
...@@ -197,30 +197,29 @@ bool TypeFeedbackOracle::StoreIsKeyedPolymorphic(TypeFeedbackId ast_id) { ...@@ -197,30 +197,29 @@ bool TypeFeedbackOracle::StoreIsKeyedPolymorphic(TypeFeedbackId ast_id) {
} }
bool TypeFeedbackOracle::CallIsMonomorphic(Call* expr) { bool TypeFeedbackOracle::CallIsMonomorphic(TypeFeedbackId id) {
Handle<Object> value = GetInfo(expr->CallFeedbackId()); Handle<Object> value = GetInfo(id);
return value->IsMap() || value->IsAllocationSite() || value->IsJSFunction() || return value->IsMap() || value->IsAllocationSite() || value->IsJSFunction() ||
value->IsSmi() || value->IsSmi() ||
(value->IsCode() && Handle<Code>::cast(value)->ic_state() == MONOMORPHIC); (value->IsCode() && Handle<Code>::cast(value)->ic_state() == MONOMORPHIC);
} }
bool TypeFeedbackOracle::KeyedArrayCallIsHoley(Call* expr) { bool TypeFeedbackOracle::KeyedArrayCallIsHoley(TypeFeedbackId id) {
Handle<Object> value = GetInfo(expr->CallFeedbackId()); Handle<Object> value = GetInfo(id);
Handle<Code> code = Handle<Code>::cast(value); Handle<Code> code = Handle<Code>::cast(value);
return KeyedArrayCallStub::IsHoley(code); return KeyedArrayCallStub::IsHoley(code);
} }
bool TypeFeedbackOracle::CallNewIsMonomorphic(CallNew* expr) { bool TypeFeedbackOracle::CallNewIsMonomorphic(TypeFeedbackId id) {
Handle<Object> info = GetInfo(expr->CallNewFeedbackId()); Handle<Object> info = GetInfo(id);
return info->IsAllocationSite() || info->IsJSFunction(); return info->IsAllocationSite() || info->IsJSFunction();
} }
bool TypeFeedbackOracle::ObjectLiteralStoreIsMonomorphic( bool TypeFeedbackOracle::ObjectLiteralStoreIsMonomorphic(TypeFeedbackId id) {
ObjectLiteral::Property* prop) { Handle<Object> map_or_code = GetInfo(id);
Handle<Object> map_or_code = GetInfo(prop->key()->LiteralFeedbackId());
return map_or_code->IsMap(); return map_or_code->IsMap();
} }
...@@ -285,22 +284,21 @@ void TypeFeedbackOracle::LoadReceiverTypes(TypeFeedbackId id, ...@@ -285,22 +284,21 @@ void TypeFeedbackOracle::LoadReceiverTypes(TypeFeedbackId id,
} }
void TypeFeedbackOracle::StoreReceiverTypes(Assignment* expr, void TypeFeedbackOracle::StoreReceiverTypes(TypeFeedbackId id,
Handle<String> name, Handle<String> name,
SmallMapList* types) { SmallMapList* types) {
Code::Flags flags = Code::ComputeFlags( Code::Flags flags = Code::ComputeFlags(
Code::HANDLER, MONOMORPHIC, kNoExtraICState, Code::HANDLER, MONOMORPHIC, kNoExtraICState,
Code::NORMAL, Code::STORE_IC); Code::NORMAL, Code::STORE_IC);
CollectReceiverTypes(expr->AssignmentFeedbackId(), name, flags, types); CollectReceiverTypes(id, name, flags, types);
} }
void TypeFeedbackOracle::CallReceiverTypes(Call* expr, void TypeFeedbackOracle::CallReceiverTypes(TypeFeedbackId id,
Handle<String> name, Handle<String> name,
int arity,
CallKind call_kind, CallKind call_kind,
SmallMapList* types) { SmallMapList* types) {
int arity = expr->arguments()->length();
// Note: Currently we do not take string extra ic data into account // Note: Currently we do not take string extra ic data into account
// here. // here.
ContextualMode contextual_mode = call_kind == CALL_AS_FUNCTION ContextualMode contextual_mode = call_kind == CALL_AS_FUNCTION
...@@ -311,12 +309,12 @@ void TypeFeedbackOracle::CallReceiverTypes(Call* expr, ...@@ -311,12 +309,12 @@ void TypeFeedbackOracle::CallReceiverTypes(Call* expr,
Code::Flags flags = Code::ComputeMonomorphicFlags( Code::Flags flags = Code::ComputeMonomorphicFlags(
Code::CALL_IC, extra_ic_state, OWN_MAP, Code::NORMAL, arity); Code::CALL_IC, extra_ic_state, OWN_MAP, Code::NORMAL, arity);
CollectReceiverTypes(expr->CallFeedbackId(), name, flags, types); CollectReceiverTypes(id, name, flags, types);
} }
CheckType TypeFeedbackOracle::GetCallCheckType(Call* expr) { CheckType TypeFeedbackOracle::GetCallCheckType(TypeFeedbackId id) {
Handle<Object> value = GetInfo(expr->CallFeedbackId()); Handle<Object> value = GetInfo(id);
if (!value->IsSmi()) return RECEIVER_MAP_CHECK; if (!value->IsSmi()) return RECEIVER_MAP_CHECK;
CheckType check = static_cast<CheckType>(Smi::cast(*value)->value()); CheckType check = static_cast<CheckType>(Smi::cast(*value)->value());
ASSERT(check != RECEIVER_MAP_CHECK); ASSERT(check != RECEIVER_MAP_CHECK);
...@@ -324,8 +322,8 @@ CheckType TypeFeedbackOracle::GetCallCheckType(Call* expr) { ...@@ -324,8 +322,8 @@ CheckType TypeFeedbackOracle::GetCallCheckType(Call* expr) {
} }
Handle<JSFunction> TypeFeedbackOracle::GetCallTarget(Call* expr) { Handle<JSFunction> TypeFeedbackOracle::GetCallTarget(TypeFeedbackId id) {
Handle<Object> info = GetInfo(expr->CallFeedbackId()); Handle<Object> info = GetInfo(id);
if (info->IsAllocationSite()) { if (info->IsAllocationSite()) {
return Handle<JSFunction>(isolate_->global_context()->array_function()); return Handle<JSFunction>(isolate_->global_context()->array_function());
} else { } else {
...@@ -334,8 +332,8 @@ Handle<JSFunction> TypeFeedbackOracle::GetCallTarget(Call* expr) { ...@@ -334,8 +332,8 @@ Handle<JSFunction> TypeFeedbackOracle::GetCallTarget(Call* expr) {
} }
Handle<JSFunction> TypeFeedbackOracle::GetCallNewTarget(CallNew* expr) { Handle<JSFunction> TypeFeedbackOracle::GetCallNewTarget(TypeFeedbackId id) {
Handle<Object> info = GetInfo(expr->CallNewFeedbackId()); Handle<Object> info = GetInfo(id);
if (info->IsAllocationSite()) { if (info->IsAllocationSite()) {
return Handle<JSFunction>(isolate_->global_context()->array_function()); return Handle<JSFunction>(isolate_->global_context()->array_function());
} else { } else {
...@@ -344,15 +342,15 @@ Handle<JSFunction> TypeFeedbackOracle::GetCallNewTarget(CallNew* expr) { ...@@ -344,15 +342,15 @@ Handle<JSFunction> TypeFeedbackOracle::GetCallNewTarget(CallNew* expr) {
} }
Handle<Cell> TypeFeedbackOracle::GetCallNewAllocationInfoCell(CallNew* expr) { Handle<Cell> TypeFeedbackOracle::GetCallNewAllocationInfoCell(
return GetInfoCell(expr->CallNewFeedbackId()); TypeFeedbackId id) {
return GetInfoCell(id);
} }
Handle<Map> TypeFeedbackOracle::GetObjectLiteralStoreMap( Handle<Map> TypeFeedbackOracle::GetObjectLiteralStoreMap(TypeFeedbackId id) {
ObjectLiteral::Property* prop) { ASSERT(ObjectLiteralStoreIsMonomorphic(id));
ASSERT(ObjectLiteralStoreIsMonomorphic(prop)); return Handle<Map>::cast(GetInfo(id));
return Handle<Map>::cast(GetInfo(prop->key()->LiteralFeedbackId()));
} }
...@@ -482,6 +480,28 @@ void TypeFeedbackOracle::KeyedPropertyReceiverTypes( ...@@ -482,6 +480,28 @@ void TypeFeedbackOracle::KeyedPropertyReceiverTypes(
} }
void TypeFeedbackOracle::AssignmentReceiverTypes(
TypeFeedbackId id, Handle<String> name, SmallMapList* receiver_types) {
receiver_types->Clear();
StoreReceiverTypes(id, name, receiver_types);
}
void TypeFeedbackOracle::KeyedAssignmentReceiverTypes(
TypeFeedbackId id, SmallMapList* receiver_types,
KeyedAccessStoreMode* store_mode) {
receiver_types->Clear();
if (StoreIsMonomorphicNormal(id)) {
// Record receiver type for monomorphic keyed stores.
receiver_types->Add(StoreMonomorphicReceiverType(id), zone());
} else if (StoreIsKeyedPolymorphic(id)) {
receiver_types->Reserve(kMaxKeyedPolymorphism, zone());
CollectKeyedReceiverTypes(id, receiver_types);
}
*store_mode = GetStoreMode(id);
}
void TypeFeedbackOracle::CountReceiverTypes( void TypeFeedbackOracle::CountReceiverTypes(
TypeFeedbackId id, SmallMapList* receiver_types) { TypeFeedbackId id, SmallMapList* receiver_types) {
receiver_types->Clear(); receiver_types->Clear();
......
...@@ -218,20 +218,9 @@ enum StringStubFeedback { ...@@ -218,20 +218,9 @@ enum StringStubFeedback {
// Forward declarations. // Forward declarations.
// TODO(rossberg): these should all go away eventually.
class Assignment;
class Call;
class CallNew;
class CaseClause;
class CompilationInfo; class CompilationInfo;
class CountOperation;
class Expression;
class ForInStatement;
class ICStub; class ICStub;
class Property;
class SmallMapList; class SmallMapList;
class ObjectLiteral;
class ObjectLiteralProperty;
class TypeFeedbackOracle: public ZoneObject { class TypeFeedbackOracle: public ZoneObject {
...@@ -245,14 +234,14 @@ class TypeFeedbackOracle: public ZoneObject { ...@@ -245,14 +234,14 @@ class TypeFeedbackOracle: public ZoneObject {
bool LoadIsUninitialized(TypeFeedbackId id); bool LoadIsUninitialized(TypeFeedbackId id);
bool LoadIsPreMonomorphic(TypeFeedbackId id); bool LoadIsPreMonomorphic(TypeFeedbackId id);
bool LoadIsPolymorphic(TypeFeedbackId id); bool LoadIsPolymorphic(TypeFeedbackId id);
bool StoreIsUninitialized(TypeFeedbackId ast_id); bool StoreIsUninitialized(TypeFeedbackId id);
bool StoreIsMonomorphicNormal(TypeFeedbackId ast_id); bool StoreIsMonomorphicNormal(TypeFeedbackId id);
bool StoreIsPreMonomorphic(TypeFeedbackId ast_id); bool StoreIsPreMonomorphic(TypeFeedbackId id);
bool StoreIsKeyedPolymorphic(TypeFeedbackId ast_id); bool StoreIsKeyedPolymorphic(TypeFeedbackId id);
bool CallIsMonomorphic(Call* expr); bool CallIsMonomorphic(TypeFeedbackId aid);
bool KeyedArrayCallIsHoley(Call* expr); bool KeyedArrayCallIsHoley(TypeFeedbackId id);
bool CallNewIsMonomorphic(CallNew* expr); bool CallNewIsMonomorphic(TypeFeedbackId id);
bool ObjectLiteralStoreIsMonomorphic(ObjectLiteralProperty* prop); bool ObjectLiteralStoreIsMonomorphic(TypeFeedbackId id);
// TODO(1571) We can't use ForInStatement::ForInType as the return value due // TODO(1571) We can't use ForInStatement::ForInType as the return value due
// to various cycles in our headers. // to various cycles in our headers.
...@@ -263,21 +252,22 @@ class TypeFeedbackOracle: public ZoneObject { ...@@ -263,21 +252,22 @@ class TypeFeedbackOracle: public ZoneObject {
Handle<Map> LoadMonomorphicReceiverType(TypeFeedbackId id); Handle<Map> LoadMonomorphicReceiverType(TypeFeedbackId id);
Handle<Map> StoreMonomorphicReceiverType(TypeFeedbackId id); Handle<Map> StoreMonomorphicReceiverType(TypeFeedbackId id);
KeyedAccessStoreMode GetStoreMode(TypeFeedbackId ast_id); KeyedAccessStoreMode GetStoreMode(TypeFeedbackId id);
void LoadReceiverTypes(TypeFeedbackId id, void LoadReceiverTypes(TypeFeedbackId id,
Handle<String> name, Handle<String> name,
SmallMapList* types); SmallMapList* types);
void StoreReceiverTypes(Assignment* expr, void StoreReceiverTypes(TypeFeedbackId id,
Handle<String> name, Handle<String> name,
SmallMapList* types); SmallMapList* types);
void CallReceiverTypes(Call* expr, void CallReceiverTypes(TypeFeedbackId id,
Handle<String> name, Handle<String> name,
int arity,
CallKind call_kind, CallKind call_kind,
SmallMapList* types); SmallMapList* types);
void CollectKeyedReceiverTypes(TypeFeedbackId ast_id, void CollectKeyedReceiverTypes(TypeFeedbackId id,
SmallMapList* types); SmallMapList* types);
void CollectPolymorphicStoreReceiverTypes(TypeFeedbackId ast_id, void CollectPolymorphicStoreReceiverTypes(TypeFeedbackId id,
SmallMapList* types); SmallMapList* types);
void PropertyReceiverTypes(TypeFeedbackId id, void PropertyReceiverTypes(TypeFeedbackId id,
...@@ -287,6 +277,12 @@ class TypeFeedbackOracle: public ZoneObject { ...@@ -287,6 +277,12 @@ class TypeFeedbackOracle: public ZoneObject {
void KeyedPropertyReceiverTypes(TypeFeedbackId id, void KeyedPropertyReceiverTypes(TypeFeedbackId id,
SmallMapList* receiver_types, SmallMapList* receiver_types,
bool* is_string); bool* is_string);
void AssignmentReceiverTypes(TypeFeedbackId id,
Handle<String> name,
SmallMapList* receiver_types);
void KeyedAssignmentReceiverTypes(TypeFeedbackId id,
SmallMapList* receiver_types,
KeyedAccessStoreMode* store_mode);
void CountReceiverTypes(TypeFeedbackId id, void CountReceiverTypes(TypeFeedbackId id,
SmallMapList* receiver_types); SmallMapList* receiver_types);
...@@ -296,12 +292,12 @@ class TypeFeedbackOracle: public ZoneObject { ...@@ -296,12 +292,12 @@ class TypeFeedbackOracle: public ZoneObject {
void CollectPolymorphicMaps(Handle<Code> code, SmallMapList* types); void CollectPolymorphicMaps(Handle<Code> code, SmallMapList* types);
CheckType GetCallCheckType(Call* expr); CheckType GetCallCheckType(TypeFeedbackId id);
Handle<JSFunction> GetCallTarget(Call* expr); Handle<JSFunction> GetCallTarget(TypeFeedbackId id);
Handle<JSFunction> GetCallNewTarget(CallNew* expr); Handle<JSFunction> GetCallNewTarget(TypeFeedbackId id);
Handle<Cell> GetCallNewAllocationInfoCell(CallNew* expr); Handle<Cell> GetCallNewAllocationInfoCell(TypeFeedbackId id);
Handle<Map> GetObjectLiteralStoreMap(ObjectLiteralProperty* prop); Handle<Map> GetObjectLiteralStoreMap(TypeFeedbackId id);
bool LoadIsBuiltin(TypeFeedbackId id, Builtins::Name builtin_id); bool LoadIsBuiltin(TypeFeedbackId id, Builtins::Name builtin_id);
bool LoadIsStub(TypeFeedbackId id, ICStub* stub); bool LoadIsStub(TypeFeedbackId id, ICStub* stub);
...@@ -332,12 +328,12 @@ class TypeFeedbackOracle: public ZoneObject { ...@@ -332,12 +328,12 @@ class TypeFeedbackOracle: public ZoneObject {
Isolate* isolate() const { return isolate_; } Isolate* isolate() const { return isolate_; }
private: private:
void CollectReceiverTypes(TypeFeedbackId ast_id, void CollectReceiverTypes(TypeFeedbackId id,
Handle<String> name, Handle<String> name,
Code::Flags flags, Code::Flags flags,
SmallMapList* types); SmallMapList* types);
void SetInfo(TypeFeedbackId ast_id, Object* target); void SetInfo(TypeFeedbackId id, Object* target);
void BuildDictionary(Handle<Code> code); void BuildDictionary(Handle<Code> code);
void GetRelocInfos(Handle<Code> code, ZoneList<RelocInfo>* infos); void GetRelocInfos(Handle<Code> code, ZoneList<RelocInfo>* infos);
...@@ -350,10 +346,10 @@ class TypeFeedbackOracle: public ZoneObject { ...@@ -350,10 +346,10 @@ class TypeFeedbackOracle: public ZoneObject {
// Returns an element from the backing store. Returns undefined if // Returns an element from the backing store. Returns undefined if
// there is no information. // there is no information.
Handle<Object> GetInfo(TypeFeedbackId ast_id); Handle<Object> GetInfo(TypeFeedbackId id);
// Return the cell that contains type feedback. // Return the cell that contains type feedback.
Handle<Cell> GetInfoCell(TypeFeedbackId ast_id); Handle<Cell> GetInfoCell(TypeFeedbackId id);
private: private:
Handle<Context> native_context_; Handle<Context> native_context_;
......
...@@ -387,31 +387,35 @@ void AstTyper::VisitArrayLiteral(ArrayLiteral* expr) { ...@@ -387,31 +387,35 @@ void AstTyper::VisitArrayLiteral(ArrayLiteral* expr) {
void AstTyper::VisitAssignment(Assignment* expr) { void AstTyper::VisitAssignment(Assignment* expr) {
// TODO(rossberg): Can we clean this up? // Collect type feedback.
if (expr->is_compound()) { Property* prop = expr->target()->AsProperty();
// Collect type feedback. if (prop != NULL) {
Expression* target = expr->target(); TypeFeedbackId id = expr->AssignmentFeedbackId();
Property* prop = target->AsProperty(); expr->set_is_uninitialized(oracle()->StoreIsUninitialized(id));
if (prop != NULL) { if (!expr->IsUninitialized()) {
RECURSE(Visit(expr->target())); expr->set_is_pre_monomorphic(oracle()->StoreIsPreMonomorphic(id));
expr->RecordTypeFeedback(oracle(), zone()); expr->set_is_monomorphic(oracle()->StoreIsMonomorphicNormal(id));
} ASSERT(!expr->IsPreMonomorphic() || !expr->IsMonomorphic());
if (prop->key()->IsPropertyName()) {
RECURSE(Visit(expr->binary_operation())); Literal* lit_key = prop->key()->AsLiteral();
ASSERT(lit_key != NULL && lit_key->value()->IsString());
NarrowType(expr, expr->binary_operation()->bounds()); Handle<String> name = Handle<String>::cast(lit_key->value());
} else { oracle()->AssignmentReceiverTypes(id, name, expr->GetReceiverTypes());
// Collect type feedback. } else {
if (expr->target()->IsProperty()) { KeyedAccessStoreMode store_mode;
expr->RecordTypeFeedback(oracle(), zone()); oracle()->KeyedAssignmentReceiverTypes(
id, expr->GetReceiverTypes(), &store_mode);
expr->set_store_mode(store_mode);
}
} }
RECURSE(Visit(expr->target()));
RECURSE(Visit(expr->value()));
NarrowType(expr, expr->value()->bounds());
} }
Expression* rhs =
expr->is_compound() ? expr->binary_operation() : expr->value();
RECURSE(Visit(expr->target()));
RECURSE(Visit(rhs));
NarrowType(expr, rhs->bounds());
VariableProxy* proxy = expr->target()->AsVariableProxy(); VariableProxy* proxy = expr->target()->AsVariableProxy();
if (proxy != NULL && proxy->var()->IsStackAllocated()) { if (proxy != NULL && proxy->var()->IsStackAllocated()) {
store_.Seq(variable_index(proxy->var()), Effect(expr->bounds())); store_.Seq(variable_index(proxy->var()), Effect(expr->bounds()));
......
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