Commit cbe088ff authored by danno@chromium.org's avatar danno@chromium.org

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