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
This commit is contained in:
danno@chromium.org 2013-02-25 14:03:09 +00:00
parent 7dd0b1ca77
commit cbe088fffc
7 changed files with 124 additions and 78 deletions

View 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);
Zone* zone = this->zone();
HEnvironment* start_environment =
new(zone) HEnvironment(zone, descriptor_->register_param_count_);
HBasicBlock* next_block = CreateBasicBlock(start_environment);
current_block()->Goto(next_block);
next_block->SetJoinId(BailoutId::StubEntry());
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_]);
HConstant* undefined_constant = new(zone()) HConstant(
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);

View 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;

View 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);

View 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();

View 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);
}

View 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:

View 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();