diff --git a/src/ast.cc b/src/ast.cc index 7edf74750b..a5d1e2df85 100644 --- a/src/ast.cc +++ b/src/ast.cc @@ -655,17 +655,15 @@ void Call::RecordTypeFeedback(TypeFeedbackOracle* oracle, void CallNew::RecordTypeFeedback(TypeFeedbackOracle* oracle) { + allocation_info_cell_ = oracle->GetCallNewAllocationInfoCell(this); is_monomorphic_ = oracle->CallNewIsMonomorphic(this); if (is_monomorphic_) { target_ = oracle->GetCallNewTarget(this); - elements_kind_ = oracle->GetCallNewElementsKind(this); + Object* value = allocation_info_cell_->value(); + if (value->IsSmi()) { + elements_kind_ = static_cast(Smi::cast(value)->value()); + } } - Handle alloc_elements_kind = oracle->GetInfo(CallNewFeedbackId()); -// if (alloc_elements_kind->IsSmi()) -// alloc_elements_kind_ = Handle::cast(alloc_elements_kind); - alloc_elements_kind_ = alloc_elements_kind->IsSmi() - ? Handle::cast(alloc_elements_kind) - : handle(Smi::FromInt(GetInitialFastElementsKind()), oracle->isolate()); } diff --git a/src/ast.h b/src/ast.h index f0b140efce..219a69bc8e 100644 --- a/src/ast.h +++ b/src/ast.h @@ -1765,7 +1765,9 @@ class CallNew: public Expression { virtual bool IsMonomorphic() { return is_monomorphic_; } Handle target() const { return target_; } ElementsKind elements_kind() const { return elements_kind_; } - Handle allocation_elements_kind() const { return alloc_elements_kind_; } + Handle allocation_info_cell() const { + return allocation_info_cell_; + } BailoutId ReturnId() const { return return_id_; } @@ -1790,7 +1792,7 @@ class CallNew: public Expression { bool is_monomorphic_; Handle target_; ElementsKind elements_kind_; - Handle alloc_elements_kind_; + Handle allocation_info_cell_; const BailoutId return_id_; }; diff --git a/src/hydrogen.cc b/src/hydrogen.cc index 14e0d4b778..0663a13745 100644 --- a/src/hydrogen.cc +++ b/src/hydrogen.cc @@ -8923,18 +8923,7 @@ void HOptimizedGraphBuilder::VisitCallNew(CallNew* expr) { CHECK_ALIVE(VisitArgumentList(expr->arguments())); HCallNew* call; if (use_call_new_array) { - // TODO(mvstanton): It would be better to use the already created global - // property cell that is shared by full code gen. That way, any transition - // information that happened after crankshaft won't be lost. The right - // way to do that is to begin passing the cell to the type feedback oracle - // instead of just the value in the cell. Do this in a follow-up checkin. - Handle feedback = expr->allocation_elements_kind(); - Handle cell = - isolate()->factory()->NewJSGlobalPropertyCell(feedback); - - // TODO(mvstanton): Here we should probably insert code to check if the - // type cell elements kind is different from when we compiled, and deopt - // in that case. Do this in a follow-up checin. + Handle cell = expr->allocation_info_cell(); call = new(zone()) HCallNewArray(context, constructor, argument_count, cell); } else { diff --git a/src/type-info.cc b/src/type-info.cc index b2840624d8..5113c550ec 100644 --- a/src/type-info.cc +++ b/src/type-info.cc @@ -78,9 +78,28 @@ static uint32_t IdToKey(TypeFeedbackId ast_id) { Handle TypeFeedbackOracle::GetInfo(TypeFeedbackId ast_id) { int entry = dictionary_->FindEntry(IdToKey(ast_id)); - return entry != UnseededNumberDictionary::kNotFound - ? Handle(dictionary_->ValueAt(entry), isolate_) - : Handle::cast(isolate_->factory()->undefined_value()); + if (entry != UnseededNumberDictionary::kNotFound) { + Object* value = dictionary_->ValueAt(entry); + if (value->IsJSGlobalPropertyCell()) { + JSGlobalPropertyCell* cell = JSGlobalPropertyCell::cast(value); + return Handle(cell->value(), isolate_); + } else { + return Handle(value, isolate_); + } + } + return Handle::cast(isolate_->factory()->undefined_value()); +} + + +Handle TypeFeedbackOracle::GetInfoCell( + TypeFeedbackId ast_id) { + int entry = dictionary_->FindEntry(IdToKey(ast_id)); + if (entry != UnseededNumberDictionary::kNotFound) { + JSGlobalPropertyCell* cell = JSGlobalPropertyCell::cast( + dictionary_->ValueAt(entry)); + return Handle(cell, isolate_); + } + return Handle::null(); } @@ -316,21 +335,12 @@ Handle TypeFeedbackOracle::GetCallNewTarget(CallNew* expr) { } -ElementsKind TypeFeedbackOracle::GetCallNewElementsKind(CallNew* expr) { - Handle info = GetInfo(expr->CallNewFeedbackId()); - if (info->IsSmi()) { - return static_cast(Smi::cast(*info)->value()); - } else { - // TODO(mvstanton): avoided calling GetInitialFastElementsKind() for perf - // reasons. Is there a better fix? - if (FLAG_packed_arrays) { - return FAST_SMI_ELEMENTS; - } else { - return FAST_HOLEY_SMI_ELEMENTS; - } - } +Handle TypeFeedbackOracle::GetCallNewAllocationInfoCell( + CallNew* expr) { + return GetInfoCell(expr->CallNewFeedbackId()); } + Handle TypeFeedbackOracle::GetObjectLiteralStoreMap( ObjectLiteral::Property* prop) { ASSERT(ObjectLiteralStoreIsMonomorphic(prop)); @@ -749,12 +759,13 @@ void TypeFeedbackOracle::ProcessTypeFeedbackCells(Handle code) { TypeFeedbackInfo::cast(raw_info)->type_feedback_cells()); for (int i = 0; i < cache->CellCount(); i++) { TypeFeedbackId ast_id = cache->AstId(i); - Object* value = cache->Cell(i)->value(); + JSGlobalPropertyCell* cell = cache->Cell(i); + Object* value = cell->value(); if (value->IsSmi() || (value->IsJSFunction() && !CanRetainOtherContext(JSFunction::cast(value), *native_context_))) { - SetInfo(ast_id, value); + SetInfo(ast_id, cell); } } } diff --git a/src/type-info.h b/src/type-info.h index 15a0b81aa6..53a83be659 100644 --- a/src/type-info.h +++ b/src/type-info.h @@ -283,7 +283,7 @@ class TypeFeedbackOracle: public ZoneObject { CheckType GetCallCheckType(Call* expr); Handle GetCallTarget(Call* expr); Handle GetCallNewTarget(CallNew* expr); - ElementsKind GetCallNewElementsKind(CallNew* expr); + Handle GetCallNewAllocationInfoCell(CallNew* expr); Handle GetObjectLiteralStoreMap(ObjectLiteralProperty* prop); @@ -338,11 +338,11 @@ class TypeFeedbackOracle: public ZoneObject { // Returns an element from the backing store. Returns undefined if // there is no information. - public: - // TODO(mvstanton): how to get this information without making the method - // public? Handle GetInfo(TypeFeedbackId ast_id); + // Return the cell that contains type feedback. + Handle GetInfoCell(TypeFeedbackId ast_id); + private: Handle native_context_; Isolate* isolate_;