CallNewArray sites need the original feedback cell at crankshaft time.
authormvstanton@chromium.org <mvstanton@chromium.org@ce2b1a6d-e550-0410-aec6-3dcde31c8c00>
Fri, 7 Jun 2013 13:21:20 +0000 (13:21 +0000)
committermvstanton@chromium.org <mvstanton@chromium.org@ce2b1a6d-e550-0410-aec6-3dcde31c8c00>
Fri, 7 Jun 2013 13:21:20 +0000 (13:21 +0000)
This CL addresses a TODO in the hydrogen-based array constructor code,
to pass through the actual type feedback cell, rather than the contents
of the cell.

BUG=
R=danno@chromium.org

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

git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@15004 ce2b1a6d-e550-0410-aec6-3dcde31c8c00

src/ast.cc
src/ast.h
src/hydrogen.cc
src/type-info.cc
src/type-info.h

index 7edf74750bca30e4f187098ec22fac855e840d9a..a5d1e2df852bca33fd5ed3d2f88c63c57f10a745 100644 (file)
@@ -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<ElementsKind>(Smi::cast(value)->value());
+    }
   }
-  Handle<Object> alloc_elements_kind = oracle->GetInfo(CallNewFeedbackId());
-//  if (alloc_elements_kind->IsSmi())
-//    alloc_elements_kind_ = Handle<Smi>::cast(alloc_elements_kind);
-  alloc_elements_kind_ = alloc_elements_kind->IsSmi()
-      ? Handle<Smi>::cast(alloc_elements_kind)
-      : handle(Smi::FromInt(GetInitialFastElementsKind()), oracle->isolate());
 }
 
 
index f0b140efceaa38e5debe40df0a0ce5e9452a97e2..219a69bc8ed3801d27e20fff45032f512fef25d4 100644 (file)
--- a/src/ast.h
+++ b/src/ast.h
@@ -1765,7 +1765,9 @@ class CallNew: public Expression {
   virtual bool IsMonomorphic() { return is_monomorphic_; }
   Handle<JSFunction> target() const { return target_; }
   ElementsKind elements_kind() const { return elements_kind_; }
-  Handle<Smi> allocation_elements_kind() const { return alloc_elements_kind_; }
+  Handle<JSGlobalPropertyCell> 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<JSFunction> target_;
   ElementsKind elements_kind_;
-  Handle<Smi> alloc_elements_kind_;
+  Handle<JSGlobalPropertyCell> allocation_info_cell_;
 
   const BailoutId return_id_;
 };
index 14e0d4b7786650d86d5d0fb18bfd9c4ab625175d..0663a1374507b4231ec045d683f2676435e4ab48 100644 (file)
@@ -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<Smi> feedback = expr->allocation_elements_kind();
-      Handle<JSGlobalPropertyCell> 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<JSGlobalPropertyCell> cell = expr->allocation_info_cell();
       call = new(zone()) HCallNewArray(context, constructor, argument_count,
                                        cell);
     } else {
index b2840624d8d9cbed3a167d410102b7031f9c3314..5113c550ecc2c9b5c4d57dbabcdbe4c2dd7bcf20 100644 (file)
@@ -78,9 +78,28 @@ static uint32_t IdToKey(TypeFeedbackId ast_id) {
 
 Handle<Object> TypeFeedbackOracle::GetInfo(TypeFeedbackId ast_id) {
   int entry = dictionary_->FindEntry(IdToKey(ast_id));
-  return entry != UnseededNumberDictionary::kNotFound
-      ? Handle<Object>(dictionary_->ValueAt(entry), isolate_)
-      : Handle<Object>::cast(isolate_->factory()->undefined_value());
+  if (entry != UnseededNumberDictionary::kNotFound) {
+    Object* value = dictionary_->ValueAt(entry);
+    if (value->IsJSGlobalPropertyCell()) {
+      JSGlobalPropertyCell* cell = JSGlobalPropertyCell::cast(value);
+      return Handle<Object>(cell->value(), isolate_);
+    } else {
+      return Handle<Object>(value, isolate_);
+    }
+  }
+  return Handle<Object>::cast(isolate_->factory()->undefined_value());
+}
+
+
+Handle<JSGlobalPropertyCell> 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<JSGlobalPropertyCell>(cell, isolate_);
+  }
+  return Handle<JSGlobalPropertyCell>::null();
 }
 
 
@@ -316,21 +335,12 @@ Handle<JSFunction> TypeFeedbackOracle::GetCallNewTarget(CallNew* expr) {
 }
 
 
-ElementsKind TypeFeedbackOracle::GetCallNewElementsKind(CallNew* expr) {
-  Handle<Object> info = GetInfo(expr->CallNewFeedbackId());
-  if (info->IsSmi()) {
-    return static_cast<ElementsKind>(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<JSGlobalPropertyCell> TypeFeedbackOracle::GetCallNewAllocationInfoCell(
+    CallNew* expr) {
+  return GetInfoCell(expr->CallNewFeedbackId());
 }
 
+
 Handle<Map> TypeFeedbackOracle::GetObjectLiteralStoreMap(
     ObjectLiteral::Property* prop) {
   ASSERT(ObjectLiteralStoreIsMonomorphic(prop));
@@ -749,12 +759,13 @@ void TypeFeedbackOracle::ProcessTypeFeedbackCells(Handle<Code> 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);
     }
   }
 }
index 15a0b81aa6a0f6211166cc1c006b0c45d35fbd7d..53a83be6595d2ef3d9ea42dbc1c4842cb0c608f4 100644 (file)
@@ -283,7 +283,7 @@ class TypeFeedbackOracle: public ZoneObject {
   CheckType GetCallCheckType(Call* expr);
   Handle<JSFunction> GetCallTarget(Call* expr);
   Handle<JSFunction> GetCallNewTarget(CallNew* expr);
-  ElementsKind GetCallNewElementsKind(CallNew* expr);
+  Handle<JSGlobalPropertyCell> GetCallNewAllocationInfoCell(CallNew* expr);
 
   Handle<Map> 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<Object> GetInfo(TypeFeedbackId ast_id);
 
+  // Return the cell that contains type feedback.
+  Handle<JSGlobalPropertyCell> GetInfoCell(TypeFeedbackId ast_id);
+
  private:
   Handle<Context> native_context_;
   Isolate* isolate_;