Fix bugs in generating and printing of Crankshaft stubs
authordanno@chromium.org <danno@chromium.org@ce2b1a6d-e550-0410-aec6-3dcde31c8c00>
Mon, 25 Feb 2013 14:03:09 +0000 (14:03 +0000)
committerdanno@chromium.org <danno@chromium.org@ce2b1a6d-e550-0410-aec6-3dcde31c8c00>
Mon, 25 Feb 2013 14:03:09 +0000 (14:03 +0000)
Review URL: https://codereview.chromium.org/12317044

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

src/code-stubs-hydrogen.cc
src/deoptimizer.cc
src/heap.cc
src/heap.h
src/hydrogen.cc
src/hydrogen.h
src/isolate.cc

index 2024d08..525c28e 100644 (file)
@@ -56,7 +56,14 @@ static LChunk* OptimizeGraph(HGraph* graph) {
 class CodeStubGraphBuilderBase : public HGraphBuilder {
  public:
   CodeStubGraphBuilderBase(Isolate* isolate, HydrogenCodeStub* stub)
-      : HGraphBuilder(&info_), info_(stub, isolate), context_(NULL) {}
+      : HGraphBuilder(&info_), info_(stub, isolate), context_(NULL) {
+    int major_key = stub->MajorKey();
+    descriptor_ = info_.isolate()->code_stub_interface_descriptor(major_key);
+    if (descriptor_->register_param_count_ < 0) {
+      stub->InitializeInterfaceDescriptor(info_.isolate(), descriptor_);
+    }
+    parameters_.Reset(new HParameter*[descriptor_->register_param_count_]);
+  }
   virtual bool BuildGraph();
 
  protected:
@@ -70,6 +77,7 @@ class CodeStubGraphBuilderBase : public HGraphBuilder {
  private:
   SmartArrayPointer<HParameter*> parameters_;
   CompilationInfoWithZone info_;
+  CodeStubInterfaceDescriptor* descriptor_;
   HContext* context_;
 };
 
@@ -81,37 +89,33 @@ bool CodeStubGraphBuilderBase::BuildGraph() {
     PrintF("Compiling stub %s using hydrogen\n", name);
     HTracer::Instance()->TraceCompilation(&info_);
   }
-  HBasicBlock* next_block = graph()->CreateBasicBlock();
-  next_block->SetInitialEnvironment(graph()->start_environment());
-  HGoto* jump = new(zone()) HGoto(next_block);
-  graph()->entry_block()->Finish(jump);
-  set_current_block(next_block);
 
-  int major_key = stub()->MajorKey();
-  CodeStubInterfaceDescriptor* descriptor =
-      info_.isolate()->code_stub_interface_descriptor(major_key);
-  if (descriptor->register_param_count_ < 0) {
-    stub()->InitializeInterfaceDescriptor(info_.isolate(), descriptor);
-  }
-  parameters_.Reset(new HParameter*[descriptor->register_param_count_]);
+  Zone* zone = this->zone();
+  HEnvironment* start_environment =
+      new(zone) HEnvironment(zone, descriptor_->register_param_count_);
+  HBasicBlock* next_block = CreateBasicBlock(start_environment);
 
-  HConstant* undefined_constant = new(zone()) HConstant(
+  current_block()->Goto(next_block);
+  next_block->SetJoinId(BailoutId::StubEntry());
+  set_current_block(next_block);
+
+  HConstant* undefined_constant = new(zone) HConstant(
       isolate()->factory()->undefined_value(), Representation::Tagged());
   AddInstruction(undefined_constant);
   graph()->set_undefined_constant(undefined_constant);
 
-  HGraph* graph = this->graph();
-  Zone* zone = this->zone();
-  for (int i = 0; i < descriptor->register_param_count_; ++i) {
+  int param_count = descriptor_->register_param_count_;
+  for (int i = 0; i < param_count; ++i) {
     HParameter* param =
         new(zone) HParameter(i, HParameter::REGISTER_PARAMETER);
     AddInstruction(param);
-    graph->start_environment()->Push(param);
+    start_environment->Bind(i, param);
     parameters_[i] = param;
   }
 
   context_ = new(zone) HContext();
   AddInstruction(context_);
+  start_environment->Bind(param_count, context_);
 
   AddSimulate(BailoutId::StubEntry());
 
@@ -184,8 +188,6 @@ void CodeStubGraphBuilder<TransitionElementsKindStub>::BuildCodeStub() {
       new(zone) HBoundsCheck(array_length, max_alloc_size,
                              DONT_ALLOW_SMI_KEY, Representation::Integer32()));
 
-  current_block()->UpdateEnvironment(new(zone) HEnvironment(zone));
-
   IfBuilder if_builder(this);
 
   if_builder.BeginTrue(array_length, graph()->GetConstant0(), Token::EQ);
index 1b177c2..b17ae5d 100644 (file)
@@ -1673,7 +1673,7 @@ int FrameDescription::ComputeParametersCount() {
       return reinterpret_cast<Smi*>(*GetFrameSlotPointer(0))->value();
     }
     case StackFrame::STUB:
-      return 0;
+      return -1;  // Minus receiver.
     default:
       UNREACHABLE();
       return 0;
index e641991..87d0cbb 100644 (file)
@@ -6209,7 +6209,7 @@ static void InitializeGCOnce() {
   MarkCompactCollector::Initialize();
 }
 
-bool Heap::SetUp(bool create_heap_objects) {
+bool Heap::SetUp() {
 #ifdef DEBUG
   allocation_timeout_ = FLAG_gc_interval;
 #endif
@@ -6300,17 +6300,6 @@ bool Heap::SetUp(bool create_heap_objects) {
     }
   }
 
-  if (create_heap_objects) {
-    // Create initial maps.
-    if (!CreateInitialMaps()) return false;
-    if (!CreateApiObjects()) return false;
-
-    // Create initial objects
-    if (!CreateInitialObjects()) return false;
-
-    native_contexts_list_ = undefined_value();
-  }
-
   LOG(isolate_, IntPtrTEvent("heap-capacity", Capacity()));
   LOG(isolate_, IntPtrTEvent("heap-available", Available()));
 
@@ -6321,6 +6310,18 @@ bool Heap::SetUp(bool create_heap_objects) {
   return true;
 }
 
+bool Heap::CreateHeapObjects() {
+  // Create initial maps.
+  if (!CreateInitialMaps()) return false;
+  if (!CreateApiObjects()) return false;
+
+  // Create initial objects
+  if (!CreateInitialObjects()) return false;
+
+  native_contexts_list_ = undefined_value();
+  return true;
+}
+
 
 void Heap::SetStackLimits() {
   ASSERT(isolate_ != NULL);
index eaa4cd0..bc79a86 100644 (file)
@@ -480,10 +480,13 @@ class Heap {
                      intptr_t max_executable_size);
   bool ConfigureHeapDefault();
 
-  // Initializes the global object heap. If create_heap_objects is true,
-  // also creates the basic non-mutable objects.
+  // Prepares the heap, setting up memory areas that are needed in the isolate
+  // without actually creating any objects.
+  bool SetUp();
+
+  // Bootstraps the object heap with the core set of objects required to run.
   // Returns whether it succeeded.
-  bool SetUp(bool create_heap_objects);
+  bool CreateHeapObjects();
 
   // Destroys all memory allocated by the heap.
   void TearDown();
index 1440fe4..9f5f7fa 100644 (file)
@@ -641,37 +641,49 @@ HGraphBuilder::IfBuilder::IfBuilder(HGraphBuilder* builder, BailoutId id)
   HEnvironment* env = builder->environment();
   HEnvironment* true_env = env->Copy();
   HEnvironment* false_env = env->Copy();
-  HEnvironment* merge_env = env->Copy();
-  true_block_ = builder->CreateBasicBlock(true_env);
-  false_block_ = builder->CreateBasicBlock(false_env);
-  merge_block_ = builder->CreateBasicBlock(merge_env);
+  first_true_block_ = builder->CreateBasicBlock(true_env);
+  last_true_block_ = NULL;
+  first_false_block_ = builder->CreateBasicBlock(false_env);
 }
 
 
-void HGraphBuilder::IfBuilder::BeginTrue(HValue* left,
-                                         HValue* right,
-                                         Token::Value token) {
+HInstruction* HGraphBuilder::IfBuilder::BeginTrue(
+    HValue* left,
+    HValue* right,
+    Token::Value token,
+    Representation input_representation) {
   HCompareIDAndBranch* compare =
       new(zone()) HCompareIDAndBranch(left, right, token);
-  compare->ChangeRepresentation(Representation::Integer32());
-  compare->SetSuccessorAt(0, true_block_);
-  compare->SetSuccessorAt(1, false_block_);
+  compare->set_observed_input_representation(input_representation,
+                                             input_representation);
+  compare->ChangeRepresentation(input_representation);
+  compare->SetSuccessorAt(0, first_true_block_);
+  compare->SetSuccessorAt(1, first_false_block_);
   builder_->current_block()->Finish(compare);
-  builder_->set_current_block(true_block_);
+  builder_->set_current_block(first_true_block_);
+  return compare;
 }
 
 
 void HGraphBuilder::IfBuilder::BeginFalse() {
-  builder_->current_block()->Goto(merge_block_);
-  builder_->set_current_block(false_block_);
+  last_true_block_ = builder_->current_block();
+  ASSERT(!last_true_block_->IsFinished());
+  builder_->set_current_block(first_false_block_);
 }
 
 
 void HGraphBuilder::IfBuilder::End() {
   ASSERT(!finished_);
-  builder_->current_block()->Goto(merge_block_);
-  builder_->set_current_block(merge_block_);
+  ASSERT(!last_true_block_->IsFinished());
+  HBasicBlock* last_false_block = builder_->current_block();
+  ASSERT(!last_false_block->IsFinished());
+  HEnvironment* merge_env =
+      last_true_block_->last_environment()->Copy();
+  merge_block_ = builder_->CreateBasicBlock(merge_env);
+  last_true_block_->Goto(merge_block_);
+  last_false_block->Goto(merge_block_);
   merge_block_->SetJoinId(id_);
+  builder_->set_current_block(merge_block_);
   finished_ = true;
 }
 
@@ -685,31 +697,38 @@ HGraphBuilder::LoopBuilder::LoopBuilder(HGraphBuilder* builder,
       direction_(direction),
       id_(id),
       finished_(false) {
-  HEnvironment* env = builder_->environment();
-  HEnvironment* body_env = env->Copy();
-  HEnvironment* exit_env = env->Copy();
   header_block_ = builder->CreateLoopHeaderBlock();
-  body_block_ = builder->CreateBasicBlock(body_env);
-  exit_block_ = builder->CreateBasicBlock(exit_env);
+  body_block_ = NULL;
+  exit_block_ = NULL;
 }
 
 
-HValue* HGraphBuilder::LoopBuilder::BeginBody(HValue* initial,
-                                              HValue* terminating,
-                                              Token::Value token) {
-  phi_ = new(zone()) HPhi(0, zone());
+HValue* HGraphBuilder::LoopBuilder::BeginBody(
+    HValue* initial,
+    HValue* terminating,
+    Token::Value token,
+    Representation input_representation) {
+  HEnvironment* env = builder_->environment();
+  phi_ = new(zone()) HPhi(env->values()->length(), zone());
   header_block_->AddPhi(phi_);
   phi_->AddInput(initial);
   phi_->ChangeRepresentation(Representation::Integer32());
-  HEnvironment* env = builder_->environment();
   env->Push(initial);
   builder_->current_block()->Goto(header_block_);
-  builder_->set_current_block(header_block_);
+
+  HEnvironment* body_env = env->Copy();
+  HEnvironment* exit_env = env->Copy();
+  body_block_ = builder_->CreateBasicBlock(body_env);
+  exit_block_ = builder_->CreateBasicBlock(exit_env);
+  // Remove the phi from the expression stack
+  body_env->Pop();
 
   builder_->set_current_block(header_block_);
   HCompareIDAndBranch* compare =
       new(zone()) HCompareIDAndBranch(phi_, terminating, token);
-  compare->ChangeRepresentation(Representation::Integer32());
+  compare->set_observed_input_representation(input_representation,
+                                             input_representation);
+  compare->ChangeRepresentation(input_representation);
   compare->SetSuccessorAt(0, body_block_);
   compare->SetSuccessorAt(1, exit_block_);
   builder_->current_block()->Finish(compare);
@@ -747,11 +766,15 @@ void HGraphBuilder::LoopBuilder::EndBody() {
     builder_->AddInstruction(increment_);
   }
 
+  // Push the new increment value on the expression stack to merge into the phi.
   builder_->environment()->Push(increment_);
   builder_->current_block()->Goto(header_block_);
   header_block_->loop_information()->RegisterBackEdge(body_block_);
-  header_block_->SetJoinId(BailoutId::StubEntry());
+  header_block_->SetJoinId(id_);
+
   builder_->set_current_block(exit_block_);
+  // Pop the phi from the expression stack
+  builder_->environment()->Pop();
   finished_ = true;
 }
 
@@ -1150,8 +1173,11 @@ HGraph::HGraph(CompilationInfo* info)
       has_soft_deoptimize_(false),
       type_change_checksum_(0) {
   if (info->IsStub()) {
+    HydrogenCodeStub* stub = info->code_stub();
+    int param_count =
+        stub->GetInterfaceDescriptor(isolate_)->register_param_count_;
     start_environment_ =
-        new(zone_) HEnvironment(zone_);
+        new(zone_) HEnvironment(zone_, param_count);
   } else {
     start_environment_ =
         new(zone_) HEnvironment(NULL, info->scope(), info->closure(), zone_);
@@ -10098,11 +10124,11 @@ HEnvironment::HEnvironment(HEnvironment* outer,
 }
 
 
-HEnvironment::HEnvironment(Zone* zone)
+HEnvironment::HEnvironment(Zone* zone, int parameter_count)
     : values_(0, zone),
       frame_type_(STUB),
-      parameter_count_(0),
-      specials_count_(0),
+      parameter_count_(parameter_count),
+      specials_count_(1),
       local_count_(0),
       outer_(NULL),
       entry_(NULL),
@@ -10110,7 +10136,7 @@ HEnvironment::HEnvironment(Zone* zone)
       push_count_(0),
       ast_id_(BailoutId::None()),
       zone_(zone) {
-  Initialize(0, 0, 0);
+  Initialize(parameter_count, 0, 0);
 }
 
 
index 0a2338a..c9bfe7e 100644 (file)
@@ -460,7 +460,7 @@ class HEnvironment: public ZoneObject {
                Handle<JSFunction> closure,
                Zone* zone);
 
-  explicit HEnvironment(Zone* zone);
+  HEnvironment(Zone* zone, int parameter_count);
 
   HEnvironment* arguments_environment() {
     return outer()->frame_type() == ARGUMENTS_ADAPTOR ? outer() : this;
@@ -928,15 +928,20 @@ class HGraphBuilder {
       if (!finished_) End();
     }
 
-    void BeginTrue(HValue* left, HValue* right, Token::Value token);
+    HInstruction* BeginTrue(
+        HValue* left,
+        HValue* right,
+        Token::Value token,
+        Representation input_representation = Representation::Integer32());
     void BeginFalse();
     void End();
 
    private:
     HGraphBuilder* builder_;
     bool finished_;
-    HBasicBlock* true_block_;
-    HBasicBlock* false_block_;
+    HBasicBlock* first_true_block_;
+    HBasicBlock* last_true_block_;
+    HBasicBlock* first_false_block_;
     HBasicBlock* merge_block_;
     BailoutId id_;
 
@@ -960,7 +965,11 @@ class HGraphBuilder {
       ASSERT(finished_);
     }
 
-    HValue* BeginBody(HValue* initial, HValue* terminating, Token::Value token);
+    HValue* BeginBody(
+        HValue* initial,
+        HValue* terminating,
+        Token::Value token,
+        Representation input_representation = Representation::Integer32());
     void EndBody();
 
    private:
index 61d2b2d..4ee3b30 100644 (file)
@@ -2039,13 +2039,20 @@ bool Isolate::Init(Deserializer* des) {
   }
 
   // SetUp the object heap.
-  const bool create_heap_objects = (des == NULL);
   ASSERT(!heap_.HasBeenSetUp());
-  if (!heap_.SetUp(create_heap_objects)) {
+  if (!heap_.SetUp()) {
     V8::FatalProcessOutOfMemory("heap setup");
     return false;
   }
 
+  deoptimizer_data_ = new DeoptimizerData;
+
+  const bool create_heap_objects = (des == NULL);
+  if (create_heap_objects && !heap_.CreateHeapObjects()) {
+    V8::FatalProcessOutOfMemory("heap object creation");
+    return false;
+  }
+
   if (create_heap_objects) {
     // Terminate the cache array with the sentinel so we can iterate.
     PushToPartialSnapshotCache(heap_.undefined_value());
@@ -2076,8 +2083,6 @@ bool Isolate::Init(Deserializer* des) {
   debug_->SetUp(create_heap_objects);
 #endif
 
-  deoptimizer_data_ = new DeoptimizerData;
-
   // If we are deserializing, read the state into the now-empty heap.
   if (!create_heap_objects) {
     des->Deserialize();