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:
private:
SmartArrayPointer<HParameter*> parameters_;
CompilationInfoWithZone info_;
+ CodeStubInterfaceDescriptor* descriptor_;
HContext* context_;
};
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());
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);
return reinterpret_cast<Smi*>(*GetFrameSlotPointer(0))->value();
}
case StackFrame::STUB:
- return 0;
+ return -1; // Minus receiver.
default:
UNREACHABLE();
return 0;
MarkCompactCollector::Initialize();
}
-bool Heap::SetUp(bool create_heap_objects) {
+bool Heap::SetUp() {
#ifdef DEBUG
allocation_timeout_ = FLAG_gc_interval;
#endif
}
}
- 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()));
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);
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();
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;
}
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);
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;
}
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_);
}
-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),
push_count_(0),
ast_id_(BailoutId::None()),
zone_(zone) {
- Initialize(0, 0, 0);
+ Initialize(parameter_count, 0, 0);
}
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;
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_;
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:
}
// 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());
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();