CodeStubGraphBuilderBase(Isolate* isolate, HydrogenCodeStub* stub)
: HGraphBuilder(&info_), info_(stub, isolate), context_(NULL) {
int major_key = stub->MajorKey();
- descriptor_ = info_.isolate()->code_stub_interface_descriptor(major_key);
+ descriptor_ = isolate->code_stub_interface_descriptor(major_key);
if (descriptor_->register_param_count_ < 0) {
- stub->InitializeInterfaceDescriptor(info_.isolate(), descriptor_);
+ stub->InitializeInterfaceDescriptor(isolate, descriptor_);
}
parameters_.Reset(new HParameter*[descriptor_->register_param_count_]);
}
const char* name = CodeStub::MajorName(stub()->MajorKey(), false);
PrintF("-----------------------------------------------------------\n");
PrintF("Compiling stub %s using hydrogen\n", name);
- HTracer::Instance()->TraceCompilation(&info_);
+ isolate()->GetHTracer()->TraceCompilation(&info_);
}
Zone* zone = this->zone();
// Fall back to using the full code generator if it's not possible
// to use the Hydrogen-based optimizing compiler. We already have
// generated code for this from the shared function object.
- if (AlwaysFullCompiler(info()->isolate())) {
+ if (AlwaysFullCompiler(isolate())) {
info()->SetCode(code);
return SetLastStatus(BAILED_OUT);
}
// performance of the hydrogen-based compiler.
bool should_recompile = !info()->shared_info()->has_deoptimization_support();
if (should_recompile || FLAG_hydrogen_stats) {
- HPhase phase(HPhase::kFullCodeGen);
+ HPhase phase(HPhase::kFullCodeGen, isolate());
CompilationInfoWithZone unoptimized(info()->shared_info());
// Note that we use the same AST that we will use for generating the
// optimized code.
if (FLAG_trace_hydrogen) {
PrintF("-----------------------------------------------------------\n");
PrintF("Compiling method %s using hydrogen\n", *name->ToCString());
- HTracer::Instance()->TraceCompilation(info());
+ isolate()->GetHTracer()->TraceCompilation(info());
}
Handle<Context> native_context(
info()->closure()->context()->native_context());
oracle_ = new(info()->zone()) TypeFeedbackOracle(
- code, native_context, info()->isolate(), info()->zone());
+ code, native_context, isolate(), info()->zone());
graph_builder_ = new(info()->zone()) HOptimizedGraphBuilder(info(), oracle_);
Timer t(this, &time_taken_to_create_graph_);
graph_ = graph_builder_->CreateGraph();
- if (info()->isolate()->has_pending_exception()) {
+ if (isolate()->has_pending_exception()) {
info()->SetCode(Handle<Code>::null());
return SetLastStatus(FAILED);
}
HGraph* HGraphBuilder::CreateGraph() {
graph_ = new(zone()) HGraph(info_);
if (FLAG_hydrogen_stats) HStatistics::Instance()->Initialize(info_);
- HPhase phase("H_Block building");
+ HPhase phase("H_Block building", graph()->isolate());
set_current_block(graph()->entry_block());
if (!BuildGraph()) return NULL;
return graph_;
void HGraph::OrderBlocks() {
- HPhase phase("H_Block ordering");
+ HPhase phase("H_Block ordering", isolate());
BitVector visited(blocks_.length(), zone());
ZoneList<HBasicBlock*> reverse_result(8, zone());
void HTracer::FlushToFile() {
- AppendChars(filename_, *trace_.ToCString(), trace_.length(), false);
+ AppendChars(filename_.start(), *trace_.ToCString(), trace_.length(), false);
trace_.Reset();
}
const char* const HPhase::kFullCodeGen = "Full code generator";
-void HPhase::Begin(const char* name,
- HGraph* graph,
- LChunk* chunk,
- LAllocator* allocator) {
+
+HPhase::HPhase(const char* name, Isolate* isolate) {
+ Init(isolate, name, NULL, NULL, NULL);
+}
+
+
+HPhase::HPhase(const char* name, HGraph* graph) {
+ Init(graph->isolate(), name, graph, NULL, NULL);
+}
+
+
+HPhase::HPhase(const char* name, LChunk* chunk) {
+ Init(chunk->graph()->isolate(), name, NULL, chunk, NULL);
+}
+
+
+HPhase::HPhase(const char* name, LAllocator* allocator) {
+ Init(allocator->graph()->isolate(), name, NULL, NULL, allocator);
+}
+
+
+void HPhase::Init(Isolate* isolate,
+ const char* name,
+ HGraph* graph,
+ LChunk* chunk,
+ LAllocator* allocator) {
+ isolate_ = isolate;
name_ = name;
graph_ = graph;
chunk_ = chunk;
if (allocator != NULL && chunk_ == NULL) {
chunk_ = allocator->chunk();
}
- if (FLAG_hydrogen_stats) start_ = OS::Ticks();
- start_allocation_size_ = Zone::allocation_size_;
+ if (FLAG_hydrogen_stats) {
+ start_ticks_ = OS::Ticks();
+ start_allocation_size_ = Zone::allocation_size_;
+ }
}
-void HPhase::End() const {
+HPhase::~HPhase() {
if (FLAG_hydrogen_stats) {
- int64_t end = OS::Ticks();
+ int64_t ticks = OS::Ticks() - start_ticks_;
unsigned size = Zone::allocation_size_ - start_allocation_size_;
- HStatistics::Instance()->SaveTiming(name_, end - start_, size);
+ HStatistics::Instance()->SaveTiming(name_, ticks, size);
}
// Produce trace output if flag is set so that the first letter of the
// phase name matches the command line parameter FLAG_trace_phase.
if (FLAG_trace_hydrogen &&
OS::StrChr(const_cast<char*>(FLAG_trace_phase), name_[0]) != NULL) {
- if (graph_ != NULL) HTracer::Instance()->TraceHydrogen(name_, graph_);
- if (chunk_ != NULL) HTracer::Instance()->TraceLithium(name_, chunk_);
+ if (graph_ != NULL) {
+ isolate_->GetHTracer()->TraceHydrogen(name_, graph_);
+ }
+ if (chunk_ != NULL) {
+ isolate_->GetHTracer()->TraceLithium(name_, chunk_);
+ }
if (allocator_ != NULL) {
- HTracer::Instance()->TraceLiveRanges(name_, allocator_);
+ isolate_->GetHTracer()->TraceLiveRanges(name_, allocator_);
}
}
public:
static const char* const kFullCodeGen;
- explicit HPhase(const char* name) { Begin(name, NULL, NULL, NULL); }
- HPhase(const char* name, HGraph* graph) {
- Begin(name, graph, NULL, NULL);
- }
- HPhase(const char* name, LChunk* chunk) {
- Begin(name, NULL, chunk, NULL);
- }
- HPhase(const char* name, LAllocator* allocator) {
- Begin(name, NULL, NULL, allocator);
- }
-
- ~HPhase() {
- End();
- }
+ HPhase(const char* name, Isolate* isolate);
+ HPhase(const char* name, HGraph* graph);
+ HPhase(const char* name, LChunk* chunk);
+ HPhase(const char* name, LAllocator* allocator);
+ ~HPhase();
private:
- void Begin(const char* name,
+ void Init(Isolate* isolate,
+ const char* name,
HGraph* graph,
LChunk* chunk,
LAllocator* allocator);
- void End() const;
- int64_t start_;
+ Isolate* isolate_;
const char* name_;
HGraph* graph_;
LChunk* chunk_;
LAllocator* allocator_;
+ int64_t start_ticks_;
unsigned start_allocation_size_;
};
class HTracer: public Malloced {
public:
+ explicit HTracer(int isolate_id)
+ : trace_(&string_allocator_), indent_(0) {
+ OS::SNPrintF(filename_,
+ "hydrogen-%d-%d.cfg",
+ OS::GetCurrentProcessId(),
+ isolate_id);
+ WriteChars(filename_.start(), "", 0, false);
+ }
+
void TraceCompilation(CompilationInfo* info);
void TraceHydrogen(const char* name, HGraph* graph);
void TraceLithium(const char* name, LChunk* chunk);
void TraceLiveRanges(const char* name, LAllocator* allocator);
- static HTracer* Instance() {
- static SetOncePointer<HTracer> instance;
- if (!instance.is_set()) {
- instance.set(new HTracer("hydrogen.cfg"));
- }
- return instance.get();
- }
-
private:
class Tag BASE_EMBEDDED {
public:
const char* name_;
};
- explicit HTracer(const char* filename)
- : filename_(filename), trace_(&string_allocator_), indent_(0) {
- WriteChars(filename, "", 0, false);
- }
-
void TraceLiveRange(LiveRange* range, const char* type, Zone* zone);
void Trace(const char* name, HGraph* graph, LChunk* chunk);
void FlushToFile();
}
}
- const char* filename_;
+ EmbeddedVector<char, 64> filename_;
HeapStringAllocator string_allocator_;
StringStream trace_;
int indent_;
Thread::LocalStorageKey Isolate::per_isolate_thread_data_key_;
Mutex* Isolate::process_wide_mutex_ = OS::CreateMutex();
Isolate::ThreadDataTable* Isolate::thread_data_table_ = NULL;
-
+Atomic32 Isolate::isolate_counter_ = 0;
Isolate::PerIsolateThreadData* Isolate::AllocatePerIsolateThreadData(
ThreadId thread_id) {
#define TRACE_ISOLATE(tag) \
do { \
if (FLAG_trace_isolates) { \
- PrintF("Isolate %p " #tag "\n", reinterpret_cast<void*>(this)); \
+ PrintF("Isolate %p (id %d)" #tag "\n", \
+ reinterpret_cast<void*>(this), id()); \
} \
} while (false)
#else
optimizing_compiler_thread_(this),
marking_thread_(NULL),
sweeper_thread_(NULL) {
+ id_ = NoBarrier_AtomicIncrement(&isolate_counter_, 1);
TRACE_ISOLATE(constructor);
memset(isolate_addresses_, 0,
}
+HTracer* Isolate::GetHTracer() {
+ if (htracer() == NULL) set_htracer(new HTracer(id()));
+ return htracer();
+}
+
+
CodeStubInterfaceDescriptor*
Isolate::code_stub_interface_descriptor(int index) {
return code_stub_interface_descriptors_ + index;
class FunctionInfoListener;
class HandleScopeImplementer;
class HeapProfiler;
+class HTracer;
class InlineRuntimeFunctionsTable;
class NoAllocationStringAllocator;
class InnerPointerToCodeCache;
V(CpuProfiler*, cpu_profiler, NULL) \
V(HeapProfiler*, heap_profiler, NULL) \
V(bool, observer_delivery_pending, false) \
+ V(HTracer*, htracer, NULL) \
ISOLATE_DEBUGGER_INIT_LIST(V)
class Isolate {
return sweeper_thread_;
}
+ HTracer* GetHTracer();
+
private:
Isolate();
+ int id() const { return static_cast<int>(id_); }
+
friend struct GlobalState;
friend struct InitializeGlobalState;
static Isolate* default_isolate_;
static ThreadDataTable* thread_data_table_;
+ // A global counter for all generated Isolates, might overflow.
+ static Atomic32 isolate_counter_;
+
void Deinit();
static void SetIsolateThreadLocals(Isolate* isolate,
// the Error object.
bool IsErrorObject(Handle<Object> obj);
+ Atomic32 id_;
EntryStackItem* entry_stack_;
int stack_trace_nesting_level_;
StringStream* incomplete_message_;