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:
parent
7dd0b1ca77
commit
cbe088fffc
@ -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);
|
||||
|
@ -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;
|
||||
|
25
src/heap.cc
25
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);
|
||||
|
@ -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();
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
|
||||
|
@ -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:
|
||||
|
@ -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();
|
||||
|
Loading…
Reference in New Issue
Block a user