From cbe088fffc1460a213f2d16fff946c8fd3041d33 Mon Sep 17 00:00:00 2001 From: "danno@chromium.org" Date: Mon, 25 Feb 2013 14:03:09 +0000 Subject: [PATCH] Fix bugs in generating and printing of Crankshaft stubs 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 | 42 +++++++++++---------- src/deoptimizer.cc | 2 +- src/heap.cc | 25 +++++++------ src/heap.h | 9 +++-- src/hydrogen.cc | 92 +++++++++++++++++++++++++++++----------------- src/hydrogen.h | 19 +++++++--- src/isolate.cc | 13 +++++-- 7 files changed, 124 insertions(+), 78 deletions(-) diff --git a/src/code-stubs-hydrogen.cc b/src/code-stubs-hydrogen.cc index 2024d08..525c28e 100644 --- a/src/code-stubs-hydrogen.cc +++ b/src/code-stubs-hydrogen.cc @@ -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 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::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); diff --git a/src/deoptimizer.cc b/src/deoptimizer.cc index 1b177c2..b17ae5d 100644 --- a/src/deoptimizer.cc +++ b/src/deoptimizer.cc @@ -1673,7 +1673,7 @@ int FrameDescription::ComputeParametersCount() { return reinterpret_cast(*GetFrameSlotPointer(0))->value(); } case StackFrame::STUB: - return 0; + return -1; // Minus receiver. default: UNREACHABLE(); return 0; diff --git a/src/heap.cc b/src/heap.cc index e641991..87d0cbb 100644 --- a/src/heap.cc +++ b/src/heap.cc @@ -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); diff --git a/src/heap.h b/src/heap.h index eaa4cd0..bc79a86 100644 --- a/src/heap.h +++ b/src/heap.h @@ -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(); diff --git a/src/hydrogen.cc b/src/hydrogen.cc index 1440fe4..9f5f7fa 100644 --- a/src/hydrogen.cc +++ b/src/hydrogen.cc @@ -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); } diff --git a/src/hydrogen.h b/src/hydrogen.h index 0a2338a..c9bfe7e 100644 --- a/src/hydrogen.h +++ b/src/hydrogen.h @@ -460,7 +460,7 @@ class HEnvironment: public ZoneObject { Handle 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: diff --git a/src/isolate.cc b/src/isolate.cc index 61d2b2d..4ee3b30 100644 --- a/src/isolate.cc +++ b/src/isolate.cc @@ -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(); -- 2.7.4