},
'cppprofilesprocessor': {
'values': ['on', 'off'],
- 'default': 'off',
+ 'default': 'on',
'help': 'enable C++ profiles processor'
},
'debuggersupport': {
namespace internal {
void CodeCreateEventRecord::UpdateCodeMap(CodeMap* code_map) {
- code_map->AddCode(start, entry, size);
+ code_map->AddCode(start, entry, size);
}
void CodeMoveEventRecord::UpdateCodeMap(CodeMap* code_map) {
- code_map->MoveCode(from, to);
+ code_map->MoveCode(from, to);
}
void CodeDeleteEventRecord::UpdateCodeMap(CodeMap* code_map) {
- code_map->DeleteCode(start);
+ code_map->DeleteCode(start);
}
void CodeAliasEventRecord::UpdateCodeMap(CodeMap* code_map) {
- code_map->AddAlias(alias, start);
+ code_map->AddAlias(alias, start);
+}
+
+
+TickSampleEventRecord* TickSampleEventRecord::init(void* value) {
+ TickSampleEventRecord* result =
+ reinterpret_cast<TickSampleEventRecord*>(value);
+ result->filler = 1;
+ ASSERT(result->filler != SamplingCircularQueue::kClear);
+ // Init the required fields only.
+ result->sample.pc = NULL;
+ result->sample.frames_count = 0;
+ return result;
}
TickSample* ProfilerEventsProcessor::TickSampleEvent() {
TickSampleEventRecord* evt =
- TickSampleEventRecord::cast(ticks_buffer_.Enqueue());
+ TickSampleEventRecord::init(ticks_buffer_.Enqueue());
evt->order = enqueue_order_; // No increment!
return &evt->sample;
}
TickSample* CpuProfiler::TickSampleEvent() {
- ASSERT(singleton_ != NULL);
- if (singleton_->is_profiling()) {
+ if (CpuProfiler::is_profiling()) {
return singleton_->processor_->TickSampleEvent();
} else {
return NULL;
void CpuProfiler::StartProcessorIfNotStarted() {
if (processor_ == NULL) {
+ // Disable logging when using the new implementation.
+ saved_logging_nesting_ = Logger::logging_nesting_;
+ Logger::logging_nesting_ = 0;
generator_ = new ProfileGenerator(profiles_);
processor_ = new ProfilerEventsProcessor(generator_);
processor_->Start();
Logger::LogAccessorCallbacks();
}
// Enable stack sampling.
- Logger::ticker_->Start();
+ reinterpret_cast<Sampler*>(Logger::ticker_)->Start();
}
}
void CpuProfiler::StopProcessorIfLastProfile() {
if (profiles_->is_last_profile()) {
- Logger::ticker_->Stop();
+ reinterpret_cast<Sampler*>(Logger::ticker_)->Stop();
processor_->Stop();
processor_->Join();
delete processor_;
delete generator_;
processor_ = NULL;
generator_ = NULL;
+ Logger::logging_nesting_ = saved_logging_nesting_;
}
}
class TickSampleEventRecord BASE_EMBEDDED {
public:
- // In memory, the first machine word of a TickSampleEventRecord will be the
- // first entry of TickSample, that is -- the VM state field.
- // TickSample is put first, because 'order' can become equal to
- // SamplingCircularQueue::kClear, while VM state can't, see
- // the definition of 'enum StateTag'.
- TickSample sample;
+ // The first machine word of a TickSampleEventRecord must not ever
+ // become equal to SamplingCircularQueue::kClear. As both order and
+ // TickSample's first field are not reliable in this sense (order
+ // can overflow, TickSample can have all fields reset), we are
+ // forced to use an artificial filler field.
+ int filler;
unsigned order;
+ TickSample sample;
static TickSampleEventRecord* cast(void* value) {
return reinterpret_cast<TickSampleEventRecord*>(value);
}
+ INLINE(static TickSampleEventRecord* init(void* value));
+
private:
DISALLOW_IMPLICIT_CONSTRUCTORS(TickSampleEventRecord);
};
unsigned next_profile_uid_;
ProfileGenerator* generator_;
ProfilerEventsProcessor* processor_;
+ int saved_logging_nesting_;
static CpuProfiler* singleton_;
DEFINE_bool(prof_lazy, false,
"Used with --prof, only does sampling and logging"
" when profiler is active (implies --noprof_auto).")
-DEFINE_bool(prof_browser_mode, false,
+DEFINE_bool(prof_browser_mode, true,
"Used with --prof, turns on browser-compatible mode for profiling.")
DEFINE_bool(log_regexp, false, "Log regular expression execution.")
DEFINE_bool(sliding_state_window, false,
// Logging and profiling.
// A StateTag represents a possible state of the VM. When compiled with
-// ENABLE_LOGGING_AND_PROFILING, the logger maintains a stack of these.
+// ENABLE_VMSTATE_TRACKING, the logger maintains a stack of these.
// Creating a VMState object enters a state by pushing on the stack, and
// destroying a VMState object leaves a state by popping the current state
// from the stack.
V(EXTERNAL)
enum StateTag {
-#ifdef ENABLE_CPP_PROFILES_PROCESSOR
- // This is to ensure that VM state field value of TickSample
- // never gets equal to SamplingCircularQueue::kClear.
- NULL_STATE = 0,
-#endif
#define DEF_STATE_TAG(name) name,
STATE_TAG_LIST(DEF_STATE_TAG)
#undef DEF_STATE_TAG
// Ticker used to provide ticks to the profiler and the sliding state
// window.
//
-#ifndef ENABLE_CPP_PROFILES_PROCESSOR
-
class Ticker: public Sampler {
public:
explicit Ticker(int interval):
Profiler* profiler_;
};
-#endif // ENABLE_CPP_PROFILES_PROCESSOR
-
//
// SlidingStateWindow implementation.
}
}
-#ifdef ENABLE_CPP_PROFILES_PROCESSOR
- // Disable old logging, as we are using the same '--prof' flag.
- logging_nesting_ = 0;
-#endif
-
LogMessageBuilder::set_write_failure_handler(StopLoggingAndProfiling);
return true;
#define LOG(Call) ((void) 0)
#endif
-#define LOG_EVENTS_AND_TAGS_LIST(V) \
+#define LOG_EVENTS_AND_TAGS_LIST_NO_NATIVES(V) \
V(CODE_CREATION_EVENT, "code-creation", "cc") \
V(CODE_MOVE_EVENT, "code-move", "cm") \
V(CODE_DELETE_EVENT, "code-delete", "cd") \
V(STORE_IC_TAG, "StoreIC", "sic") \
V(STUB_TAG, "Stub", "s")
+#ifdef ENABLE_CPP_PROFILES_PROCESSOR
+// Add 'NATIVE_' cases for functions and scripts, but map them to
+// original tags when writing to the log.
+#define LOG_EVENTS_AND_TAGS_LIST(V) \
+ LOG_EVENTS_AND_TAGS_LIST_NO_NATIVES(V) \
+ V(NATIVE_FUNCTION_TAG, "Function", "f") \
+ V(NATIVE_LAZY_COMPILE_TAG, "LazyCompile", "lc") \
+ V(NATIVE_SCRIPT_TAG, "Script", "sc")
+#else
+#define LOG_EVENTS_AND_TAGS_LIST(V) LOG_EVENTS_AND_TAGS_LIST_NO_NATIVES(V)
+#endif
+
class Logger {
public:
#define DECLARE_ENUM(enum_item, ignore1, ignore2) enum_item,
enum LogEventsAndTags {
LOG_EVENTS_AND_TAGS_LIST(DECLARE_ENUM)
NUMBER_OF_LOG_EVENTS
-#ifdef ENABLE_CPP_PROFILES_PROCESSOR
- , NATIVE_FUNCTION_TAG
- , NATIVE_LAZY_COMPILE_TAG
- , NATIVE_SCRIPT_TAG
-#endif
};
#undef DECLARE_ENUM
static void Trace(TickSample* sample);
};
-
-#ifdef ENABLE_CPP_PROFILES_PROCESSOR
-
-class Ticker: public Sampler {
- public:
- explicit Ticker(int interval):
- Sampler(interval, FLAG_prof) {}
-
- void SampleStack(TickSample* sample) {
- StackTracer::Trace(sample);
- }
- void Tick(TickSample* sample) { }
- void SetWindow(SlidingStateWindow* window) { }
- void ClearWindow() { }
- void SetProfiler(Profiler* profiler) { }
- void ClearProfiler() { }
-};
-
-#endif // ENABLE_CPP_PROFILES_PROCESSOR
-
} } // namespace v8::internal
if (signal != SIGPROF) return;
if (active_sampler_ == NULL) return;
-#ifdef ENABLE_CPP_PROFILES_PROCESSOR
- TickSample* sample = CpuProfiler::TickSampleEvent();
- if (sample == NULL) return;
- sample->pc = NULL; // Impossible value if sampling succeeds.
- sample->frames_count = 0;
-#else
TickSample sample_obj;
- TickSample* sample = &sample_obj;
+ TickSample* sample = NULL;
+#ifdef ENABLE_CPP_PROFILES_PROCESSOR
+ sample = CpuProfiler::TickSampleEvent();
#endif
+ if (sample == NULL) sample = &sample_obj;
// We always sample the VM state.
sample->state = VMState::current_state();
active_sampler_->SampleStack(sample);
}
}
-#ifndef ENABLE_CPP_PROFILES_PROCESSOR
+
active_sampler_->Tick(sample);
#endif
-#endif
}
void Runner() {
// Loop until the sampler is disengaged, keeping the specified samling freq.
for ( ; sampler_->IsActive(); OS::Sleep(sampler_->interval_)) {
-#ifdef ENABLE_CPP_PROFILES_PROCESSOR
- TickSample* sample = CpuProfiler::TickSampleEvent();
- if (sample == NULL) continue;
- sample->pc = NULL; // Impossible value if sampling succeeds.
- sample->frames_count = 0;
-#else
TickSample sample_obj;
- TickSample* sample = &sample_obj;
-#endif // ENABLE_CPP_PROFILES_PROCESSOR
+ TickSample* sample = NULL;
+#ifdef ENABLE_CPP_PROFILES_PROCESSOR
+ sample = CpuProfiler::TickSampleEvent();
+#endif
+ if (sample == NULL) sample = &sample_obj;
// We always sample the VM state.
sample->state = VMState::current_state();
thread_resume(profiled_thread_);
}
-#ifndef ENABLE_CPP_PROFILES_PROCESSOR
// Invoke tick handler with program counter and stack pointer.
sampler_->Tick(sample);
-#endif
}
}
};
memset(&context, 0, sizeof(context));
// Loop until the sampler is disengaged, keeping the specified samling freq.
for ( ; sampler_->IsActive(); Sleep(sampler_->interval_)) {
-#ifdef ENABLE_CPP_PROFILES_PROCESSOR
- TickSample* sample = CpuProfiler::TickSampleEvent();
- if (sample == NULL) continue;
- sample->pc = NULL; // Impossible value if sampling succeeds.
- sample->frames_count = 0;
-#else
TickSample sample_obj;
- TickSample* sample = &sample_obj;
-#endif // ENABLE_CPP_PROFILES_PROCESSOR
+ TickSample* sample = NULL;
+#ifdef ENABLE_CPP_PROFILES_PROCESSOR
+ sample = CpuProfiler::TickSampleEvent();
+#endif
+ if (sample == NULL) sample = &sample_obj;
// We always sample the VM state.
sample->state = VMState::current_state();
ResumeThread(profiled_thread_);
}
-#ifndef ENABLE_CPP_PROFILES_PROCESSOR
// Invoke tick handler with program counter and stack pointer.
sampler_->Tick(sample);
-#endif
}
}
};
CpuProfiler::Setup();
-#ifdef ENABLE_CPP_PROFILES_PROCESSOR
- if (FLAG_prof && FLAG_prof_auto) {
- CpuProfiler::StartProfiling("internal.auto");
- }
-#endif
-
// Setup the platform OS support.
OS::Setup();
void V8::TearDown() {
if (!has_been_setup_ || has_been_disposed_) return;
-#ifdef ENABLE_CPP_PROFILES_PROCESSOR
- if (FLAG_prof && FLAG_prof_auto) {
- CpuProfiler::StopProfiling("internal.auto");
- }
-#endif
-
OProfileAgent::TearDown();
if (FLAG_preemption) {
i::Address frame2 = NULL,
i::Address frame3 = NULL) {
i::TickSample* sample = proc->TickSampleEvent();
- sample->state = i::OTHER;
sample->pc = frame1;
sample->function = frame1;
sample->frames_count = 0;
}
}
+namespace {
+
+class TestSetup {
+ public:
+ TestSetup()
+ : old_flag_prof_browser_mode_(i::FLAG_prof_browser_mode) {
+ i::FLAG_prof_browser_mode = false;
+ }
+
+ ~TestSetup() {
+ i::FLAG_prof_browser_mode = old_flag_prof_browser_mode_;
+ }
+
+ private:
+ bool old_flag_prof_browser_mode_;
+};
+
+} // namespace
+
TEST(CodeEvents) {
InitializeVM();
+ TestSetup test_setup;
CpuProfilesCollection profiles;
profiles.StartProfiling("", 1);
ProfileGenerator generator(&profiles);
}
TEST(TickEvents) {
+ TestSetup test_setup;
CpuProfilesCollection profiles;
profiles.StartProfiling("", 1);
ProfileGenerator generator(&profiles);
}
+namespace {
+
+class TestSetup {
+ public:
+ TestSetup()
+ : old_flag_prof_browser_mode_(i::FLAG_prof_browser_mode) {
+ i::FLAG_prof_browser_mode = false;
+ }
+
+ ~TestSetup() {
+ i::FLAG_prof_browser_mode = old_flag_prof_browser_mode_;
+ }
+
+ private:
+ bool old_flag_prof_browser_mode_;
+};
+
+} // namespace
+
TEST(RecordTickSample) {
+ TestSetup test_setup;
CpuProfilesCollection profiles;
profiles.StartProfiling("", 1);
ProfileGenerator generator(&profiles);
'ENABLE_LOGGING_AND_PROFILING',
'ENABLE_DEBUGGER_SUPPORT',
'ENABLE_VMSTATE_TRACKING',
+ 'ENABLE_CPP_PROFILES_PROCESSOR',
],
'conditions': [
['target_arch=="arm"', {