NULL,
Code::ComputeFlags(Code::REGEXP),
masm_->CodeObject());
- LOG(RegExpCodeCreateEvent(*code, *source));
+ PROFILE(RegExpCodeCreateEvent(*code, *source));
return Handle<Object>::cast(code);
}
}
}
// Log the event and add the code to the builtins array.
- LOG(CodeCreateEvent(Logger::BUILTIN_TAG,
- Code::cast(code), functions[i].s_name));
+ PROFILE(CodeCreateEvent(Logger::BUILTIN_TAG,
+ Code::cast(code), functions[i].s_name));
builtins_[i] = code;
#ifdef ENABLE_DISASSEMBLER
if (FLAG_print_builtin_code) {
OPROFILE(CreateNativeCodeRegion(GetName(),
code->instruction_start(),
code->instruction_size()));
- LOG(CodeCreateEvent(Logger::STUB_TAG, code, GetName()));
+ PROFILE(CodeCreateEvent(Logger::STUB_TAG, code, GetName()));
Counters::total_stubs_code_size.Increment(code->instruction_size());
#ifdef ENABLE_DISASSEMBLER
bool CodeGenerator::ShouldGenerateLog(Expression* type) {
ASSERT(type != NULL);
- if (!Logger::is_logging()) return false;
+ if (!Logger::is_logging() && !CpuProfiler::is_profiling()) return false;
Handle<String> name = Handle<String>::cast(type->AsLiteral()->handle());
if (FLAG_log_regexp) {
static Vector<const char> kRegexp = CStrVector("regexp");
}
if (script->name()->IsString()) {
- LOG(CodeCreateEvent(is_eval ? Logger::EVAL_TAG : Logger::SCRIPT_TAG,
- *code, String::cast(script->name())));
+ PROFILE(CodeCreateEvent(is_eval ? Logger::EVAL_TAG : Logger::SCRIPT_TAG,
+ *code, String::cast(script->name())));
OPROFILE(CreateNativeCodeRegion(String::cast(script->name()),
code->instruction_start(),
code->instruction_size()));
} else {
- LOG(CodeCreateEvent(is_eval ? Logger::EVAL_TAG : Logger::SCRIPT_TAG,
- *code, ""));
+ PROFILE(CodeCreateEvent(is_eval ? Logger::EVAL_TAG : Logger::SCRIPT_TAG,
+ *code, ""));
OPROFILE(CreateNativeCodeRegion(is_eval ? "Eval" : "Script",
code->instruction_start(),
code->instruction_size()));
// Log the code generation. If source information is available
// include script name and line number. Check explicitly whether
// logging is enabled as finding the line number is not free.
- if (Logger::is_logging() || OProfileAgent::is_enabled()) {
+ if (Logger::is_logging()
+ || OProfileAgent::is_enabled()
+ || CpuProfiler::is_profiling()) {
Handle<String> func_name(name->length() > 0 ? *name : *inferred_name);
if (script->name()->IsString()) {
int line_num = GetScriptLineNumber(script, start_position) + 1;
USE(line_num);
- LOG(CodeCreateEvent(tag, *code, *func_name,
- String::cast(script->name()), line_num));
+ PROFILE(CodeCreateEvent(tag, *code, *func_name,
+ String::cast(script->name()), line_num));
OPROFILE(CreateNativeCodeRegion(*func_name,
String::cast(script->name()),
line_num,
code->instruction_start(),
code->instruction_size()));
} else {
- LOG(CodeCreateEvent(tag, *code, *func_name));
+ PROFILE(CodeCreateEvent(tag, *code, *func_name));
OPROFILE(CreateNativeCodeRegion(*func_name,
code->instruction_start(),
code->instruction_size()));
#ifndef V8_CPU_PROFILER_INL_H_
#define V8_CPU_PROFILER_INL_H_
+#include "cpu-profiler.h"
+
#ifdef ENABLE_CPP_PROFILES_PROCESSOR
#include "circular-queue-inl.h"
#include "profile-generator-inl.h"
-#include "cpu-profiler.h"
-
namespace v8 {
namespace internal {
+void CodeCreateEventRecord::UpdateCodeMap(CodeMap* code_map) {
+ code_map->AddCode(start, entry, size);
+}
+
+
+void CodeMoveEventRecord::UpdateCodeMap(CodeMap* code_map) {
+ code_map->MoveCode(from, to);
+}
+
+
+void CodeDeleteEventRecord::UpdateCodeMap(CodeMap* code_map) {
+ code_map->DeleteCode(start);
+}
+
+
+void CodeAliasEventRecord::UpdateCodeMap(CodeMap* code_map) {
+ code_map->AddAlias(alias, start);
+}
+
+
TickSample* ProfilerEventsProcessor::TickSampleEvent() {
TickSampleEventRecord* evt =
TickSampleEventRecord::cast(ticks_buffer_.Enqueue());
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-#ifdef ENABLE_CPP_PROFILES_PROCESSOR
-
#include "v8.h"
#include "cpu-profiler-inl.h"
+#ifdef ENABLE_CPP_PROFILES_PROCESSOR
+
+#include "log-inl.h"
+
namespace v8 {
namespace internal {
enqueue_order_(0) { }
+void ProfilerEventsProcessor::CallbackCreateEvent(Logger::LogEventsAndTags tag,
+ const char* prefix,
+ String* name,
+ Address start) {
+ CodeEventsContainer evt_rec;
+ CodeCreateEventRecord* rec = &evt_rec.CodeCreateEventRecord_;
+ rec->type = CodeEventRecord::CODE_CREATION;
+ rec->order = ++enqueue_order_;
+ rec->start = start;
+ rec->entry = generator_->NewCodeEntry(tag, prefix, name);
+ rec->size = 1;
+ events_buffer_.Enqueue(evt_rec);
+}
+
+
void ProfilerEventsProcessor::CodeCreateEvent(Logger::LogEventsAndTags tag,
String* name,
String* resource_name,
while (ProcessTicks(dequeue_order) && ProcessCodeEvent(&dequeue_order)) { }
}
+
+CpuProfiler* CpuProfiler::singleton_ = NULL;
+
+void CpuProfiler::StartProfiling(const char* title) {
+ ASSERT(singleton_ != NULL);
+ singleton_->StartCollectingProfile(title);
+}
+
+
+void CpuProfiler::StartProfiling(String* title) {
+ ASSERT(singleton_ != NULL);
+ singleton_->StartCollectingProfile(title);
+}
+
+
+CpuProfile* CpuProfiler::StopProfiling(const char* title) {
+ ASSERT(singleton_ != NULL);
+ return singleton_->StopCollectingProfile(title);
+}
+
+
+CpuProfile* CpuProfiler::StopProfiling(String* title) {
+ ASSERT(singleton_ != NULL);
+ return singleton_->StopCollectingProfile(title);
+}
+
+
+int CpuProfiler::GetProfilesCount() {
+ ASSERT(singleton_ != NULL);
+ return singleton_->profiles_->profiles()->length();
+}
+
+
+CpuProfile* CpuProfiler::GetProfile(int index) {
+ ASSERT(singleton_ != NULL);
+ return singleton_->profiles_->profiles()->at(index);
+}
+
+
+CpuProfile* CpuProfiler::FindProfile(unsigned uid) {
+ ASSERT(singleton_ != NULL);
+ return singleton_->profiles_->GetProfile(uid);
+}
+
+
+TickSample* CpuProfiler::TickSampleEvent() {
+ ASSERT(singleton_ != NULL);
+ if (singleton_->is_profiling()) {
+ return singleton_->processor_->TickSampleEvent();
+ } else {
+ return NULL;
+ }
+}
+
+
+void CpuProfiler::CallbackEvent(String* name, Address entry_point) {
+ singleton_->processor_->CallbackCreateEvent(
+ Logger::CALLBACK_TAG, CodeEntry::kEmptyNamePrefix, name, entry_point);
+}
+
+
+void CpuProfiler::CodeCreateEvent(Logger::LogEventsAndTags tag,
+ Code* code, const char* comment) {
+ singleton_->processor_->CodeCreateEvent(
+ tag, comment, code->address(), code->ExecutableSize());
+}
+
+
+void CpuProfiler::CodeCreateEvent(Logger::LogEventsAndTags tag,
+ Code* code, String* name) {
+ singleton_->processor_->CodeCreateEvent(
+ tag,
+ name,
+ Heap::empty_string(),
+ CodeEntry::kNoLineNumberInfo,
+ code->address(),
+ code->ExecutableSize());
+}
+
+
+void CpuProfiler::CodeCreateEvent(Logger::LogEventsAndTags tag,
+ Code* code, String* name,
+ String* source, int line) {
+ singleton_->processor_->CodeCreateEvent(
+ tag,
+ name,
+ source,
+ line,
+ code->address(),
+ code->ExecutableSize());
+}
+
+
+void CpuProfiler::CodeCreateEvent(Logger::LogEventsAndTags tag,
+ Code* code, int args_count) {
+ singleton_->processor_->CodeCreateEvent(
+ tag,
+ args_count,
+ code->address(),
+ code->ExecutableSize());
+}
+
+
+void CpuProfiler::CodeMoveEvent(Address from, Address to) {
+ singleton_->processor_->CodeMoveEvent(from, to);
+}
+
+
+void CpuProfiler::CodeDeleteEvent(Address from) {
+ singleton_->processor_->CodeDeleteEvent(from);
+}
+
+
+void CpuProfiler::FunctionCreateEvent(JSFunction* function) {
+ singleton_->processor_->FunctionCreateEvent(
+ function->address(), function->code()->address());
+}
+
+
+void CpuProfiler::FunctionMoveEvent(Address from, Address to) {
+ singleton_->processor_->FunctionMoveEvent(from, to);
+}
+
+
+void CpuProfiler::FunctionDeleteEvent(Address from) {
+ singleton_->processor_->FunctionDeleteEvent(from);
+}
+
+
+void CpuProfiler::GetterCallbackEvent(String* name, Address entry_point) {
+ singleton_->processor_->CallbackCreateEvent(
+ Logger::CALLBACK_TAG, "get ", name, entry_point);
+}
+
+
+void CpuProfiler::RegExpCodeCreateEvent(Code* code, String* source) {
+ singleton_->processor_->CodeCreateEvent(
+ Logger::REG_EXP_TAG,
+ source,
+ Heap::empty_string(),
+ CodeEntry::kNoLineNumberInfo,
+ code->address(),
+ code->ExecutableSize());
+}
+
+
+void CpuProfiler::SetterCallbackEvent(String* name, Address entry_point) {
+ singleton_->processor_->CallbackCreateEvent(
+ Logger::CALLBACK_TAG, "set ", name, entry_point);
+}
+
+
+CpuProfiler::CpuProfiler()
+ : profiles_(new CpuProfilesCollection()),
+ next_profile_uid_(1),
+ generator_(NULL),
+ processor_(NULL) {
+}
+
+
+CpuProfiler::~CpuProfiler() {
+ delete profiles_;
+}
+
+
+void CpuProfiler::StartCollectingProfile(const char* title) {
+ if (profiles_->StartProfiling(title, ++next_profile_uid_)) {
+ StartProcessorIfNotStarted();
+ }
+}
+
+
+void CpuProfiler::StartCollectingProfile(String* title) {
+ if (profiles_->StartProfiling(title, ++next_profile_uid_)) {
+ StartProcessorIfNotStarted();
+ }
+}
+
+
+void CpuProfiler::StartProcessorIfNotStarted() {
+ if (processor_ == NULL) {
+ generator_ = new ProfileGenerator(profiles_);
+ processor_ = new ProfilerEventsProcessor(generator_);
+ processor_->Start();
+ // Enumerate stuff we already have in the heap.
+ if (Heap::HasBeenSetup()) {
+ Logger::LogCodeObjects();
+ Logger::LogCompiledFunctions();
+ Logger::LogFunctionObjects();
+ Logger::LogAccessorCallbacks();
+ }
+ // Enable stack sampling.
+ Logger::ticker_->Start();
+ }
+}
+
+
+CpuProfile* CpuProfiler::StopCollectingProfile(const char* title) {
+ StopProcessorIfLastProfile();
+ CpuProfile* result = profiles_->StopProfiling(title);
+ if (result != NULL) {
+ result->Print();
+ }
+ return result;
+}
+
+
+CpuProfile* CpuProfiler::StopCollectingProfile(String* title) {
+ StopProcessorIfLastProfile();
+ return profiles_->StopProfiling(title);
+}
+
+
+void CpuProfiler::StopProcessorIfLastProfile() {
+ if (profiles_->is_last_profile()) {
+ Logger::ticker_->Stop();
+ processor_->Stop();
+ processor_->Join();
+ delete processor_;
+ delete generator_;
+ processor_ = NULL;
+ generator_ = NULL;
+ }
+}
+
} } // namespace v8::internal
#endif // ENABLE_CPP_PROFILES_PROCESSOR
+
+namespace v8 {
+namespace internal {
+
+void CpuProfiler::Setup() {
+#ifdef ENABLE_CPP_PROFILES_PROCESSOR
+ if (singleton_ == NULL) {
+ singleton_ = new CpuProfiler();
+ }
+#endif
+}
+
+
+void CpuProfiler::TearDown() {
+#ifdef ENABLE_CPP_PROFILES_PROCESSOR
+ if (singleton_ != NULL) {
+ delete singleton_;
+ }
+ singleton_ = NULL;
+#endif
+}
+
+} } // namespace v8::internal
#ifdef ENABLE_CPP_PROFILES_PROCESSOR
#include "circular-queue.h"
-#include "profile-generator.h"
namespace v8 {
namespace internal {
+// Forward declarations.
+class CodeEntry;
+class CodeMap;
+class CpuProfile;
+class CpuProfilesCollection;
+class ProfileGenerator;
+
+
#define CODE_EVENTS_TYPE_LIST(V) \
V(CODE_CREATION, CodeCreateEventRecord) \
V(CODE_MOVE, CodeMoveEventRecord) \
CodeEntry* entry;
unsigned size;
- INLINE(void UpdateCodeMap(CodeMap* code_map)) {
- code_map->AddCode(start, entry, size);
- }
+ INLINE(void UpdateCodeMap(CodeMap* code_map));
};
Address from;
Address to;
- INLINE(void UpdateCodeMap(CodeMap* code_map)) {
- code_map->MoveCode(from, to);
- }
+ INLINE(void UpdateCodeMap(CodeMap* code_map));
};
public:
Address start;
- INLINE(void UpdateCodeMap(CodeMap* code_map)) {
- code_map->DeleteCode(start);
- }
+ INLINE(void UpdateCodeMap(CodeMap* code_map));
};
Address alias;
Address start;
- INLINE(void UpdateCodeMap(CodeMap* code_map)) {
- code_map->AddAlias(alias, start);
- }
+ INLINE(void UpdateCodeMap(CodeMap* code_map));
};
INLINE(bool running()) { return running_; }
// Events adding methods. Called by VM threads.
+ void CallbackCreateEvent(Logger::LogEventsAndTags tag,
+ const char* prefix, String* name,
+ Address start);
void CodeCreateEvent(Logger::LogEventsAndTags tag,
String* name,
String* resource_name, int line_number,
} } // namespace v8::internal
+
+#define PROFILE(Call) \
+ LOG(Call); \
+ do { \
+ if (v8::internal::CpuProfiler::is_profiling()) { \
+ v8::internal::CpuProfiler::Call; \
+ } \
+ } while (false)
+#else
+#define PROFILE(Call) LOG(Call)
+#endif // ENABLE_CPP_PROFILES_PROCESSOR
+
+
+namespace v8 {
+namespace internal {
+
+class CpuProfiler {
+ public:
+ static void Setup();
+ static void TearDown();
+
+#ifdef ENABLE_CPP_PROFILES_PROCESSOR
+ static void StartProfiling(const char* title);
+ static void StartProfiling(String* title);
+ static CpuProfile* StopProfiling(const char* title);
+ static CpuProfile* StopProfiling(String* title);
+ static int GetProfilesCount();
+ static CpuProfile* GetProfile(int index);
+ static CpuProfile* FindProfile(unsigned uid);
+
+ // Invoked from stack sampler (thread or signal handler.)
+ static TickSample* TickSampleEvent();
+
+ // Must be called via PROFILE macro, otherwise will crash when
+ // profiling is not enabled.
+ static void CallbackEvent(String* name, Address entry_point);
+ static void CodeCreateEvent(Logger::LogEventsAndTags tag,
+ Code* code, const char* comment);
+ static void CodeCreateEvent(Logger::LogEventsAndTags tag,
+ Code* code, String* name);
+ static void CodeCreateEvent(Logger::LogEventsAndTags tag,
+ Code* code, String* name,
+ String* source, int line);
+ static void CodeCreateEvent(Logger::LogEventsAndTags tag,
+ Code* code, int args_count);
+ static void CodeMoveEvent(Address from, Address to);
+ static void CodeDeleteEvent(Address from);
+ static void FunctionCreateEvent(JSFunction* function);
+ static void FunctionMoveEvent(Address from, Address to);
+ static void FunctionDeleteEvent(Address from);
+ static void GetterCallbackEvent(String* name, Address entry_point);
+ static void RegExpCodeCreateEvent(Code* code, String* source);
+ static void SetterCallbackEvent(String* name, Address entry_point);
+
+ static INLINE(bool is_profiling()) {
+ ASSERT(singleton_ != NULL);
+ return singleton_->processor_ != NULL;
+ }
+
+ private:
+ CpuProfiler();
+ ~CpuProfiler();
+ void StartCollectingProfile(const char* title);
+ void StartCollectingProfile(String* title);
+ void StartProcessorIfNotStarted();
+ CpuProfile* StopCollectingProfile(const char* title);
+ CpuProfile* StopCollectingProfile(String* title);
+ void StopProcessorIfLastProfile();
+
+ CpuProfilesCollection* profiles_;
+ unsigned next_profile_uid_;
+ ProfileGenerator* generator_;
+ ProfilerEventsProcessor* processor_;
+
+ static CpuProfiler* singleton_;
+
+#else
+ static INLINE(bool is_profiling()) { return false; }
#endif // ENABLE_CPP_PROFILES_PROCESSOR
+ private:
+ DISALLOW_COPY_AND_ASSIGN(CpuProfiler);
+};
+
+} } // namespace v8::internal
+
+
#endif // V8_CPU_PROFILER_H_
ClearExceptionFlag flag) {
CompilationInfo info(function, 0, receiver);
bool result = CompileLazyHelper(&info, flag);
- LOG(FunctionCreateEvent(*function));
+ PROFILE(FunctionCreateEvent(*function));
return result;
}
ClearExceptionFlag flag) {
CompilationInfo info(function, 1, receiver);
bool result = CompileLazyHelper(&info, flag);
- LOG(FunctionCreateEvent(*function));
+ PROFILE(FunctionCreateEvent(*function));
return result;
}
Code::ComputeFlags(Code::STUB),
Handle<Code>::null());
if (!code->IsCode()) return;
- LOG(CodeCreateEvent(Logger::BUILTIN_TAG,
- Code::cast(code), "CpuFeatures::Probe"));
+ PROFILE(CodeCreateEvent(Logger::BUILTIN_TAG,
+ Code::cast(code), "CpuFeatures::Probe"));
typedef uint64_t (*F0)();
F0 probe = FUNCTION_CAST<F0>(Code::cast(code)->entry());
supported_ = probe();
NULL,
Code::ComputeFlags(Code::REGEXP),
masm_->CodeObject());
- LOG(RegExpCodeCreateEvent(*code, *source));
+ PROFILE(RegExpCodeCreateEvent(*code, *source));
return Handle<Object>::cast(code);
}
// StackTracer implementation
//
void StackTracer::Trace(TickSample* sample) {
- if (sample->state == GC) {
- sample->frames_count = 0;
- return;
- }
+ sample->function = NULL;
+ sample->frames_count = 0;
+
+ if (sample->state == GC) return;
const Address js_entry_sp = Top::js_entry_sp(Top::GetCurrentThread());
if (js_entry_sp == 0) {
// Not executing JS now.
- sample->frames_count = 0;
return;
}
// 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.
tag = Logger::CALL_IC_TAG;
break;
}
- LOG(CodeCreateEvent(tag, code_object, description));
+ PROFILE(CodeCreateEvent(tag, code_object, description));
}
}
Handle<String> script_name(String::cast(script->name()));
int line_num = GetScriptLineNumber(script, shared->start_position());
if (line_num > 0) {
- LOG(CodeCreateEvent(Logger::LAZY_COMPILE_TAG,
- shared->code(), *func_name,
- *script_name, line_num + 1));
+ PROFILE(CodeCreateEvent(Logger::LAZY_COMPILE_TAG,
+ shared->code(), *func_name,
+ *script_name, line_num + 1));
} else {
// Can't distinguish enum and script here, so always use Script.
- LOG(CodeCreateEvent(Logger::SCRIPT_TAG,
- shared->code(), *script_name));
+ PROFILE(CodeCreateEvent(Logger::SCRIPT_TAG,
+ shared->code(), *script_name));
}
} else {
- LOG(CodeCreateEvent(
+ PROFILE(CodeCreateEvent(
Logger::LAZY_COMPILE_TAG, shared->code(), *func_name));
}
} else if (shared->IsApiFunction()) {
CallHandlerInfo* call_data = CallHandlerInfo::cast(raw_call_data);
Object* callback_obj = call_data->callback();
Address entry_point = v8::ToCData<Address>(callback_obj);
- LOG(CallbackEvent(*func_name, entry_point));
+ PROFILE(CallbackEvent(*func_name, entry_point));
}
} else {
- LOG(CodeCreateEvent(
+ PROFILE(CodeCreateEvent(
Logger::LAZY_COMPILE_TAG, shared->code(), *func_name));
}
}
if (!obj->IsJSFunction()) continue;
JSFunction* jsf = JSFunction::cast(obj);
if (!jsf->is_compiled()) continue;
- LOG(FunctionCreateEvent(jsf));
+ PROFILE(FunctionCreateEvent(jsf));
}
}
String* name = String::cast(ai->name());
Address getter_entry = v8::ToCData<Address>(ai->getter());
if (getter_entry != 0) {
- LOG(GetterCallbackEvent(name, getter_entry));
+ PROFILE(GetterCallbackEvent(name, getter_entry));
}
Address setter_entry = v8::ToCData<Address>(ai->setter());
if (setter_entry != 0) {
- LOG(SetterCallbackEvent(name, setter_entry));
+ PROFILE(SetterCallbackEvent(name, setter_entry));
}
}
}
}
}
+#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;
#endif
}
-
} } // namespace v8::internal
#define LOG(Call) ((void) 0)
#endif
-
class VMState BASE_EMBEDDED {
#ifdef ENABLE_LOGGING_AND_PROFILING
public:
static int logging_nesting_;
static int cpu_profiler_nesting_;
static int heap_profiler_nesting_;
+
+ friend class CpuProfiler;
#else
static bool is_logging() { return false; }
#endif
};
+#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
+
#endif // V8_LOG_H_
HeapObject* copied_to = HeapObject::FromAddress(new_addr);
if (copied_to->IsJSFunction()) {
- LOG(FunctionMoveEvent(old_addr, new_addr));
+ PROFILE(FunctionMoveEvent(old_addr, new_addr));
}
return obj_size;
// May also update inline cache target.
Code::cast(copied_to)->Relocate(new_addr - old_addr);
// Notify the logger that compiled code has moved.
- LOG(CodeMoveEvent(old_addr, new_addr));
+ PROFILE(CodeMoveEvent(old_addr, new_addr));
}
return obj_size;
HeapObject* copied_to = HeapObject::FromAddress(new_addr);
if (copied_to->IsJSFunction()) {
- LOG(FunctionMoveEvent(old_addr, new_addr));
+ PROFILE(FunctionMoveEvent(old_addr, new_addr));
}
return obj_size;
void MarkCompactCollector::ReportDeleteIfNeeded(HeapObject* obj) {
#ifdef ENABLE_LOGGING_AND_PROFILING
if (obj->IsCode()) {
- LOG(CodeDeleteEvent(obj->address()));
+ PROFILE(CodeDeleteEvent(obj->address()));
} else if (obj->IsJSFunction()) {
- LOG(FunctionDeleteEvent(obj->address()));
+ PROFILE(FunctionDeleteEvent(obj->address()));
}
#endif
}
if (signal != SIGPROF) return;
if (active_sampler_ == NULL) return;
- TickSample sample;
+#ifdef ENABLE_CPP_PROFILES_PROCESSOR
+ if (Logger::state() == GC || !IsVmThread()) return;
+
+ TickSample* sample = NULL;
+#else
+ TickSample sample_obj;
+ TickSample* sample = &sample_obj;
// We always sample the VM state.
- sample.state = Logger::state();
+ sample->state = Logger::state();
+#endif
// If profiling, we extract the current pc and sp.
if (active_sampler_->IsProfiling()) {
// Extracting the sample from the context is extremely machine dependent.
ucontext_t* ucontext = reinterpret_cast<ucontext_t*>(context);
mcontext_t& mcontext = ucontext->uc_mcontext;
+#ifdef ENABLE_CPP_PROFILES_PROCESSOR
+ sample = CpuProfiler::TickSampleEvent();
+#endif
+ if (sample != NULL) {
#if V8_HOST_ARCH_IA32
- sample.pc = reinterpret_cast<Address>(mcontext.gregs[REG_EIP]);
- sample.sp = reinterpret_cast<Address>(mcontext.gregs[REG_ESP]);
- sample.fp = reinterpret_cast<Address>(mcontext.gregs[REG_EBP]);
+ sample->pc = reinterpret_cast<Address>(mcontext.gregs[REG_EIP]);
+ sample->sp = reinterpret_cast<Address>(mcontext.gregs[REG_ESP]);
+ sample->fp = reinterpret_cast<Address>(mcontext.gregs[REG_EBP]);
#elif V8_HOST_ARCH_X64
- sample.pc = reinterpret_cast<Address>(mcontext.gregs[REG_RIP]);
- sample.sp = reinterpret_cast<Address>(mcontext.gregs[REG_RSP]);
- sample.fp = reinterpret_cast<Address>(mcontext.gregs[REG_RBP]);
+ sample->pc = reinterpret_cast<Address>(mcontext.gregs[REG_RIP]);
+ sample->sp = reinterpret_cast<Address>(mcontext.gregs[REG_RSP]);
+ sample->fp = reinterpret_cast<Address>(mcontext.gregs[REG_RBP]);
#elif V8_HOST_ARCH_ARM
// An undefined macro evaluates to 0, so this applies to Android's Bionic also.
#if (__GLIBC__ < 2 || (__GLIBC__ == 2 && __GLIBC_MINOR__ <= 3))
- sample.pc = reinterpret_cast<Address>(mcontext.gregs[R15]);
- sample.sp = reinterpret_cast<Address>(mcontext.gregs[R13]);
- sample.fp = reinterpret_cast<Address>(mcontext.gregs[R11]);
+ sample->pc = reinterpret_cast<Address>(mcontext.gregs[R15]);
+ sample->sp = reinterpret_cast<Address>(mcontext.gregs[R13]);
+ sample->fp = reinterpret_cast<Address>(mcontext.gregs[R11]);
#else
- sample.pc = reinterpret_cast<Address>(mcontext.arm_pc);
- sample.sp = reinterpret_cast<Address>(mcontext.arm_sp);
- sample.fp = reinterpret_cast<Address>(mcontext.arm_fp);
+ sample->pc = reinterpret_cast<Address>(mcontext.arm_pc);
+ sample->sp = reinterpret_cast<Address>(mcontext.arm_sp);
+ sample->fp = reinterpret_cast<Address>(mcontext.arm_fp);
#endif
#elif V8_HOST_ARCH_MIPS
// Implement this on MIPS.
- UNIMPLEMENTED();
+ UNIMPLEMENTED();
+#endif
+#ifdef ENABLE_CPP_PROFILES_PROCESSOR
+ active_sampler_->SampleStack(sample);
+#else
+ if (IsVmThread()) {
+ active_sampler_->SampleStack(sample);
+ }
#endif
- if (IsVmThread())
- active_sampler_->SampleStack(&sample);
+ }
}
-
- active_sampler_->Tick(&sample);
+#ifndef ENABLE_CPP_PROFILES_PROCESSOR
+ active_sampler_->Tick(sample);
+#endif
#endif
}
// Sampler thread handler.
void Runner() {
- // Loop until the sampler is disengaged.
- while (sampler_->IsActive()) {
- TickSample sample;
+ // Loop until the sampler is disengaged, keeping the specified samling freq.
+ for ( ; sampler_->IsActive(); OS::Sleep(sampler_->interval_)) {
+#ifdef ENABLE_CPP_PROFILES_PROCESSOR
+ if (Logger::state() == GC) continue;
+
+ TickSample* sample = NULL;
+#else
+ TickSample sample_obj;
+ TickSample* sample = &sample_obj;
// We always sample the VM state.
- sample.state = Logger::state();
+ sample->state = Logger::state();
+#endif // ENABLE_CPP_PROFILES_PROCESSOR
// If profiling, we record the pc and sp of the profiled thread.
if (sampler_->IsProfiling()
flavor,
reinterpret_cast<natural_t*>(&state),
&count) == KERN_SUCCESS) {
- sample.pc = reinterpret_cast<Address>(state.REGISTER_FIELD(ip));
- sample.sp = reinterpret_cast<Address>(state.REGISTER_FIELD(sp));
- sample.fp = reinterpret_cast<Address>(state.REGISTER_FIELD(bp));
- sampler_->SampleStack(&sample);
+#ifdef ENABLE_CPP_PROFILES_PROCESSOR
+ sample = CpuProfiler::TickSampleEvent();
+#endif
+ if (sample != NULL) {
+ sample->pc = reinterpret_cast<Address>(state.REGISTER_FIELD(ip));
+ sample->sp = reinterpret_cast<Address>(state.REGISTER_FIELD(sp));
+ sample->fp = reinterpret_cast<Address>(state.REGISTER_FIELD(bp));
+ sampler_->SampleStack(sample);
+ }
}
thread_resume(profiled_thread_);
}
+#ifndef ENABLE_CPP_PROFILES_PROCESSOR
// Invoke tick handler with program counter and stack pointer.
- sampler_->Tick(&sample);
-
- // Wait until next sampling.
- usleep(sampler_->interval_ * 1000);
+ sampler_->Tick(sample);
+#endif
}
}
};
// Context used for sampling the register state of the profiled thread.
CONTEXT context;
memset(&context, 0, sizeof(context));
- // Loop until the sampler is disengaged.
- while (sampler_->IsActive()) {
- TickSample sample;
+ // Loop until the sampler is disengaged, keeping the specified samling freq.
+ for ( ; sampler_->IsActive(); Sleep(sampler_->interval_)) {
+#ifdef ENABLE_CPP_PROFILES_PROCESSOR
+ if (Logger::state() == GC) continue;
+
+ TickSample* sample = NULL;
+#else
+ TickSample sample_obj;
+ TickSample* sample = &sample_obj;
// We always sample the VM state.
- sample.state = Logger::state();
+ sample->state = Logger::state();
+#endif // ENABLE_CPP_PROFILES_PROCESSOR
// If profiling, we record the pc and sp of the profiled thread.
if (sampler_->IsProfiling()
&& SuspendThread(profiled_thread_) != (DWORD)-1) {
context.ContextFlags = CONTEXT_FULL;
if (GetThreadContext(profiled_thread_, &context) != 0) {
+#ifdef ENABLE_CPP_PROFILES_PROCESSOR
+ sample = CpuProfiler::TickSampleEvent();
+#endif
+ if (sample != NULL) {
#if V8_HOST_ARCH_X64
- sample.pc = reinterpret_cast<Address>(context.Rip);
- sample.sp = reinterpret_cast<Address>(context.Rsp);
- sample.fp = reinterpret_cast<Address>(context.Rbp);
+ sample->pc = reinterpret_cast<Address>(context.Rip);
+ sample->sp = reinterpret_cast<Address>(context.Rsp);
+ sample->fp = reinterpret_cast<Address>(context.Rbp);
#else
- sample.pc = reinterpret_cast<Address>(context.Eip);
- sample.sp = reinterpret_cast<Address>(context.Esp);
- sample.fp = reinterpret_cast<Address>(context.Ebp);
+ sample->pc = reinterpret_cast<Address>(context.Eip);
+ sample->sp = reinterpret_cast<Address>(context.Esp);
+ sample->fp = reinterpret_cast<Address>(context.Ebp);
#endif
- sampler_->SampleStack(&sample);
+ sampler_->SampleStack(sample);
+ }
}
ResumeThread(profiled_thread_);
}
+#ifndef ENABLE_CPP_PROFILES_PROCESSOR
// Invoke tick handler with program counter and stack pointer.
- sampler_->Tick(&sample);
-
- // Wait until next sampling.
- Sleep(sampler_->interval_);
+ sampler_->Tick(sample);
+#endif
}
}
};
Address fp; // Frame pointer.
Address function; // The last called JS function.
StateTag state; // The state of the VM.
- static const int kMaxFramesCount = 100;
+ static const int kMaxFramesCount = 64;
Address stack[kMaxFramesCount]; // Call stack.
int frames_count; // Number of captured frames.
};
namespace internal {
CodeEntry::CodeEntry(Logger::LogEventsAndTags tag,
+ const char* name_prefix,
const char* name,
const char* resource_name,
int line_number)
: tag_(tag),
+ name_prefix_(name_prefix),
name_(name),
resource_name_(resource_name),
line_number_(line_number) {
}
-bool CodeEntry::is_js_function() {
+bool CodeEntry::is_js_function() const {
return tag_ == Logger::FUNCTION_TAG
|| tag_ == Logger::LAZY_COMPILE_TAG
|| tag_ == Logger::SCRIPT_TAG;
namespace v8 {
namespace internal {
+
+const char* CodeEntry::kEmptyNamePrefix = "";
+const int CodeEntry::kNoLineNumberInfo = -1;
+
+
ProfileNode* ProfileNode::FindChild(CodeEntry* entry) {
HashMap::Entry* map_entry =
children_.Lookup(entry, CodeEntryHash(entry), false);
void ProfileNode::Print(int indent) {
- OS::Print("%5u %5u %*c %s\n",
+ OS::Print("%5u %5u %*c %s%s\n",
total_ticks_, self_ticks_,
indent, ' ',
+ entry_ != NULL ? entry_->name_prefix() : "",
entry_ != NULL ? entry_->name() : "");
for (HashMap::Entry* p = children_.Start();
p != NULL;
String* resource_name,
int line_number) {
CodeEntry* entry = new CodeEntry(tag,
+ CodeEntry::kEmptyNamePrefix,
GetName(name),
GetName(resource_name),
line_number);
CodeEntry* CpuProfilesCollection::NewCodeEntry(Logger::LogEventsAndTags tag,
const char* name) {
CodeEntry* entry = new CodeEntry(tag,
+ CodeEntry::kEmptyNamePrefix,
name,
"",
- kNoLineNumberInfo);
+ CodeEntry::kNoLineNumberInfo);
+ code_entries_.Add(entry);
+ return entry;
+}
+
+
+CodeEntry* CpuProfilesCollection::NewCodeEntry(Logger::LogEventsAndTags tag,
+ const char* name_prefix,
+ String* name) {
+ CodeEntry* entry = new CodeEntry(tag,
+ name_prefix,
+ GetName(name),
+ "",
+ CodeEntry::kNoLineNumberInfo);
code_entries_.Add(entry);
return entry;
}
CodeEntry* CpuProfilesCollection::NewCodeEntry(Logger::LogEventsAndTags tag,
int args_count) {
CodeEntry* entry = new CodeEntry(tag,
+ "args_count: ",
GetName(args_count),
"",
- kNoLineNumberInfo);
+ CodeEntry::kNoLineNumberInfo);
code_entries_.Add(entry);
return entry;
}
if (args_count_names_[args_count] == NULL) {
const int kMaximumNameLength = 32;
char* name = NewArray<char>(kMaximumNameLength);
- OS::SNPrintF(Vector<char>(name, kMaximumNameLength),
- "args_count: %d", args_count);
+ OS::SNPrintF(Vector<char>(name, kMaximumNameLength), "%d", args_count);
args_count_names_[args_count] = name;
}
return args_count_names_[args_count];
class CodeEntry {
public:
// CodeEntry doesn't own name strings, just references them.
- INLINE(CodeEntry(Logger::LogEventsAndTags tag_,
- const char* name_,
- const char* resource_name_,
- int line_number_));
-
- INLINE(bool is_js_function());
- INLINE(const char* name()) { return name_; }
- INLINE(const char* resource_name()) { return name_; }
- INLINE(int line_number()) { return line_number_; }
+ INLINE(CodeEntry(Logger::LogEventsAndTags tag,
+ const char* name_prefix,
+ const char* name,
+ const char* resource_name,
+ int line_number));
+
+ INLINE(bool is_js_function() const);
+ INLINE(const char* name_prefix() const) { return name_prefix_; }
+ INLINE(bool has_name_prefix() const) { return name_prefix_[0] != '\0'; }
+ INLINE(const char* name() const) { return name_; }
+ INLINE(const char* resource_name() const) { return resource_name_; }
+ INLINE(int line_number() const) { return line_number_; }
+
+ static const char* kEmptyNamePrefix;
+ static const int kNoLineNumberInfo;
private:
Logger::LogEventsAndTags tag_;
+ const char* name_prefix_;
const char* name_;
const char* resource_name_;
int line_number_;
CodeEntry* NewCodeEntry(Logger::LogEventsAndTags tag,
String* name, String* resource_name, int line_number);
CodeEntry* NewCodeEntry(Logger::LogEventsAndTags tag, const char* name);
+ CodeEntry* NewCodeEntry(Logger::LogEventsAndTags tag,
+ const char* name_prefix, String* name);
CodeEntry* NewCodeEntry(Logger::LogEventsAndTags tag, int args_count);
// Called from profile generator thread.
void AddPathToCurrentProfiles(const Vector<CodeEntry*>& path);
- // This will be moved to V8 API.
- static const int kNoLineNumberInfo = -1;
-
private:
const char* GetName(String* name);
const char* GetName(int args_count);
return profiles_->NewCodeEntry(tag, name);
}
+ INLINE(CodeEntry* NewCodeEntry(Logger::LogEventsAndTags tag,
+ const char* name_prefix,
+ String* name)) {
+ return profiles_->NewCodeEntry(tag, name_prefix, name);
+ }
+
INLINE(CodeEntry* NewCodeEntry(Logger::LogEventsAndTags tag,
int args_count)) {
return profiles_->NewCodeEntry(tag, args_count);
LoadStubCompiler compiler;
code = compiler.CompileLoadField(receiver, holder, field_index, name);
if (code->IsFailure()) return code;
- LOG(CodeCreateEvent(Logger::LOAD_IC_TAG, Code::cast(code), name));
+ PROFILE(CodeCreateEvent(Logger::LOAD_IC_TAG, Code::cast(code), name));
Object* result = receiver->map()->UpdateCodeCache(name, Code::cast(code));
if (result->IsFailure()) return result;
}
LoadStubCompiler compiler;
code = compiler.CompileLoadCallback(name, receiver, holder, callback);
if (code->IsFailure()) return code;
- LOG(CodeCreateEvent(Logger::LOAD_IC_TAG, Code::cast(code), name));
+ PROFILE(CodeCreateEvent(Logger::LOAD_IC_TAG, Code::cast(code), name));
Object* result = receiver->map()->UpdateCodeCache(name, Code::cast(code));
if (result->IsFailure()) return result;
}
LoadStubCompiler compiler;
code = compiler.CompileLoadConstant(receiver, holder, value, name);
if (code->IsFailure()) return code;
- LOG(CodeCreateEvent(Logger::LOAD_IC_TAG, Code::cast(code), name));
+ PROFILE(CodeCreateEvent(Logger::LOAD_IC_TAG, Code::cast(code), name));
Object* result = receiver->map()->UpdateCodeCache(name, Code::cast(code));
if (result->IsFailure()) return result;
}
LoadStubCompiler compiler;
code = compiler.CompileLoadInterceptor(receiver, holder, name);
if (code->IsFailure()) return code;
- LOG(CodeCreateEvent(Logger::LOAD_IC_TAG, Code::cast(code), name));
+ PROFILE(CodeCreateEvent(Logger::LOAD_IC_TAG, Code::cast(code), name));
Object* result = receiver->map()->UpdateCodeCache(name, Code::cast(code));
if (result->IsFailure()) return result;
}
name,
is_dont_delete);
if (code->IsFailure()) return code;
- LOG(CodeCreateEvent(Logger::LOAD_IC_TAG, Code::cast(code), name));
+ PROFILE(CodeCreateEvent(Logger::LOAD_IC_TAG, Code::cast(code), name));
Object* result = receiver->map()->UpdateCodeCache(name, Code::cast(code));
if (result->IsFailure()) return result;
}
KeyedLoadStubCompiler compiler;
code = compiler.CompileLoadField(name, receiver, holder, field_index);
if (code->IsFailure()) return code;
- LOG(CodeCreateEvent(Logger::KEYED_LOAD_IC_TAG, Code::cast(code), name));
+ PROFILE(CodeCreateEvent(Logger::KEYED_LOAD_IC_TAG, Code::cast(code), name));
Object* result = receiver->map()->UpdateCodeCache(name, Code::cast(code));
if (result->IsFailure()) return result;
}
KeyedLoadStubCompiler compiler;
code = compiler.CompileLoadConstant(name, receiver, holder, value);
if (code->IsFailure()) return code;
- LOG(CodeCreateEvent(Logger::KEYED_LOAD_IC_TAG, Code::cast(code), name));
+ PROFILE(CodeCreateEvent(Logger::KEYED_LOAD_IC_TAG, Code::cast(code), name));
Object* result = receiver->map()->UpdateCodeCache(name, Code::cast(code));
if (result->IsFailure()) return result;
}
KeyedLoadStubCompiler compiler;
code = compiler.CompileLoadInterceptor(receiver, holder, name);
if (code->IsFailure()) return code;
- LOG(CodeCreateEvent(Logger::KEYED_LOAD_IC_TAG, Code::cast(code), name));
+ PROFILE(CodeCreateEvent(Logger::KEYED_LOAD_IC_TAG, Code::cast(code), name));
Object* result = receiver->map()->UpdateCodeCache(name, Code::cast(code));
if (result->IsFailure()) return result;
}
KeyedLoadStubCompiler compiler;
code = compiler.CompileLoadCallback(name, receiver, holder, callback);
if (code->IsFailure()) return code;
- LOG(CodeCreateEvent(Logger::KEYED_LOAD_IC_TAG, Code::cast(code), name));
+ PROFILE(CodeCreateEvent(Logger::KEYED_LOAD_IC_TAG, Code::cast(code), name));
Object* result = receiver->map()->UpdateCodeCache(name, Code::cast(code));
if (result->IsFailure()) return result;
}
KeyedLoadStubCompiler compiler;
code = compiler.CompileLoadArrayLength(name);
if (code->IsFailure()) return code;
- LOG(CodeCreateEvent(Logger::KEYED_LOAD_IC_TAG, Code::cast(code), name));
+ PROFILE(CodeCreateEvent(Logger::KEYED_LOAD_IC_TAG, Code::cast(code), name));
Object* result = receiver->map()->UpdateCodeCache(name, Code::cast(code));
if (result->IsFailure()) return result;
}
KeyedLoadStubCompiler compiler;
code = compiler.CompileLoadStringLength(name);
if (code->IsFailure()) return code;
- LOG(CodeCreateEvent(Logger::KEYED_LOAD_IC_TAG, Code::cast(code), name));
+ PROFILE(CodeCreateEvent(Logger::KEYED_LOAD_IC_TAG, Code::cast(code), name));
Object* result = receiver->map()->UpdateCodeCache(name, Code::cast(code));
if (result->IsFailure()) return result;
}
KeyedLoadStubCompiler compiler;
code = compiler.CompileLoadFunctionPrototype(name);
if (code->IsFailure()) return code;
- LOG(CodeCreateEvent(Logger::KEYED_LOAD_IC_TAG, Code::cast(code), name));
+ PROFILE(CodeCreateEvent(Logger::KEYED_LOAD_IC_TAG, Code::cast(code), name));
Object* result = receiver->map()->UpdateCodeCache(name, Code::cast(code));
if (result->IsFailure()) return result;
}
StoreStubCompiler compiler;
code = compiler.CompileStoreField(receiver, field_index, transition, name);
if (code->IsFailure()) return code;
- LOG(CodeCreateEvent(Logger::STORE_IC_TAG, Code::cast(code), name));
+ PROFILE(CodeCreateEvent(Logger::STORE_IC_TAG, Code::cast(code), name));
Object* result = receiver->map()->UpdateCodeCache(name, Code::cast(code));
if (result->IsFailure()) return result;
}
StoreStubCompiler compiler;
code = compiler.CompileStoreGlobal(receiver, cell, name);
if (code->IsFailure()) return code;
- LOG(CodeCreateEvent(Logger::LOAD_IC_TAG, Code::cast(code), name));
+ PROFILE(CodeCreateEvent(Logger::LOAD_IC_TAG, Code::cast(code), name));
Object* result = receiver->map()->UpdateCodeCache(name, Code::cast(code));
if (result->IsFailure()) return result;
}
StoreStubCompiler compiler;
code = compiler.CompileStoreCallback(receiver, callback, name);
if (code->IsFailure()) return code;
- LOG(CodeCreateEvent(Logger::STORE_IC_TAG, Code::cast(code), name));
+ PROFILE(CodeCreateEvent(Logger::STORE_IC_TAG, Code::cast(code), name));
Object* result = receiver->map()->UpdateCodeCache(name, Code::cast(code));
if (result->IsFailure()) return result;
}
StoreStubCompiler compiler;
code = compiler.CompileStoreInterceptor(receiver, name);
if (code->IsFailure()) return code;
- LOG(CodeCreateEvent(Logger::STORE_IC_TAG, Code::cast(code), name));
+ PROFILE(CodeCreateEvent(Logger::STORE_IC_TAG, Code::cast(code), name));
Object* result = receiver->map()->UpdateCodeCache(name, Code::cast(code));
if (result->IsFailure()) return result;
}
KeyedStoreStubCompiler compiler;
code = compiler.CompileStoreField(receiver, field_index, transition, name);
if (code->IsFailure()) return code;
- LOG(CodeCreateEvent(Logger::KEYED_STORE_IC_TAG, Code::cast(code), name));
+ PROFILE(CodeCreateEvent(
+ Logger::KEYED_STORE_IC_TAG, Code::cast(code), name));
Object* result = receiver->map()->UpdateCodeCache(name, Code::cast(code));
if (result->IsFailure()) return result;
}
code = compiler.CompileCallConstant(object, holder, function, name, check);
if (code->IsFailure()) return code;
ASSERT_EQ(flags, Code::cast(code)->flags());
- LOG(CodeCreateEvent(Logger::CALL_IC_TAG, Code::cast(code), name));
+ PROFILE(CodeCreateEvent(Logger::CALL_IC_TAG, Code::cast(code), name));
Object* result = map->UpdateCodeCache(name, Code::cast(code));
if (result->IsFailure()) return result;
}
name);
if (code->IsFailure()) return code;
ASSERT_EQ(flags, Code::cast(code)->flags());
- LOG(CodeCreateEvent(Logger::CALL_IC_TAG, Code::cast(code), name));
+ PROFILE(CodeCreateEvent(Logger::CALL_IC_TAG, Code::cast(code), name));
Object* result = map->UpdateCodeCache(name, Code::cast(code));
if (result->IsFailure()) return result;
}
name);
if (code->IsFailure()) return code;
ASSERT_EQ(flags, Code::cast(code)->flags());
- LOG(CodeCreateEvent(Logger::CALL_IC_TAG, Code::cast(code), name));
+ PROFILE(CodeCreateEvent(Logger::CALL_IC_TAG, Code::cast(code), name));
Object* result = map->UpdateCodeCache(name, Code::cast(code));
if (result->IsFailure()) return result;
}
code = compiler.CompileCallGlobal(receiver, holder, cell, function, name);
if (code->IsFailure()) return code;
ASSERT_EQ(flags, Code::cast(code)->flags());
- LOG(CodeCreateEvent(Logger::CALL_IC_TAG, Code::cast(code), name));
+ PROFILE(CodeCreateEvent(Logger::CALL_IC_TAG, Code::cast(code), name));
Object* result = receiver->map()->UpdateCodeCache(name, Code::cast(code));
if (result->IsFailure()) return result;
}
if (result->IsCode()) {
Code* code = Code::cast(result);
USE(code);
- LOG(CodeCreateEvent(Logger::LAZY_COMPILE_TAG,
- code, code->arguments_count()));
+ PROFILE(CodeCreateEvent(Logger::LAZY_COMPILE_TAG,
+ code, code->arguments_count()));
}
return result;
}
Counters::call_initialize_stubs.Increment();
Code* code = Code::cast(result);
USE(code);
- LOG(CodeCreateEvent(Logger::CALL_INITIALIZE_TAG,
- code, code->arguments_count()));
+ PROFILE(CodeCreateEvent(Logger::CALL_INITIALIZE_TAG,
+ code, code->arguments_count()));
}
return result;
}
Counters::call_premonomorphic_stubs.Increment();
Code* code = Code::cast(result);
USE(code);
- LOG(CodeCreateEvent(Logger::CALL_PRE_MONOMORPHIC_TAG,
- code, code->arguments_count()));
+ PROFILE(CodeCreateEvent(Logger::CALL_PRE_MONOMORPHIC_TAG,
+ code, code->arguments_count()));
}
return result;
}
Counters::call_normal_stubs.Increment();
Code* code = Code::cast(result);
USE(code);
- LOG(CodeCreateEvent(Logger::CALL_NORMAL_TAG,
- code, code->arguments_count()));
+ PROFILE(CodeCreateEvent(Logger::CALL_NORMAL_TAG,
+ code, code->arguments_count()));
}
return result;
}
Counters::call_megamorphic_stubs.Increment();
Code* code = Code::cast(result);
USE(code);
- LOG(CodeCreateEvent(Logger::CALL_MEGAMORPHIC_TAG,
- code, code->arguments_count()));
+ PROFILE(CodeCreateEvent(Logger::CALL_MEGAMORPHIC_TAG,
+ code, code->arguments_count()));
}
return result;
}
Counters::call_megamorphic_stubs.Increment();
Code* code = Code::cast(result);
USE(code);
- LOG(CodeCreateEvent(Logger::CALL_MISS_TAG, code, code->arguments_count()));
+ PROFILE(CodeCreateEvent(Logger::CALL_MISS_TAG,
+ code, code->arguments_count()));
}
return result;
}
if (!result->IsFailure()) {
Code* code = Code::cast(result);
USE(code);
- LOG(CodeCreateEvent(Logger::CALL_DEBUG_BREAK_TAG,
- code, code->arguments_count()));
+ PROFILE(CodeCreateEvent(Logger::CALL_DEBUG_BREAK_TAG,
+ code, code->arguments_count()));
}
return result;
}
if (!result->IsFailure()) {
Code* code = Code::cast(result);
USE(code);
- LOG(CodeCreateEvent(Logger::CALL_DEBUG_PREPARE_STEP_IN_TAG,
- code, code->arguments_count()));
+ PROFILE(CodeCreateEvent(Logger::CALL_DEBUG_PREPARE_STEP_IN_TAG,
+ code, code->arguments_count()));
}
return result;
}
if (!result->IsFailure()) {
Code* code = Code::cast(result);
USE(code);
- LOG(CodeCreateEvent(Logger::STUB_TAG, code, "ConstructStub"));
+ PROFILE(CodeCreateEvent(Logger::STUB_TAG, code, "ConstructStub"));
}
return result;
}
// Enable logging before setting up the heap
Logger::Setup();
+ 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) {
Top::TearDown();
Heap::TearDown();
+
+ CpuProfiler::TearDown();
+
Logger::TearDown();
is_running_ = false;
#include "spaces-inl.h"
#include "heap-inl.h"
#include "log-inl.h"
+#include "cpu-profiler-inl.h"
#include "handles-inl.h"
namespace v8 {
Object* code =
Heap::CreateCode(desc, NULL, Code::ComputeFlags(Code::STUB), NULL);
if (!code->IsCode()) return;
- LOG(CodeCreateEvent(Logger::BUILTIN_TAG,
- Code::cast(code), "CpuFeatures::Probe"));
+ PROFILE(CodeCreateEvent(Logger::BUILTIN_TAG,
+ Code::cast(code), "CpuFeatures::Probe"));
typedef uint64_t (*F0)();
F0 probe = FUNCTION_CAST<F0>(Code::cast(code)->entry());
supported_ = probe();
NULL,
Code::ComputeFlags(Code::REGEXP),
masm_->CodeObject());
- LOG(RegExpCodeCreateEvent(*code, *source));
+ PROFILE(RegExpCodeCreateEvent(*code, *source));
return Handle<Object>::cast(code);
}
CHECK_EQ("bbb", entry2->name());
CodeEntry* entry3 = generator.code_map()->FindEntry(ToAddress(0x1300));
CHECK_NE(NULL, entry3);
- CHECK_EQ("args_count: 5", entry3->name());
+ CHECK_EQ("5", entry3->name());
CHECK_EQ(NULL, generator.code_map()->FindEntry(ToAddress(0x1400)));
CodeEntry* entry4 = generator.code_map()->FindEntry(ToAddress(0x1500));
CHECK_NE(NULL, entry4);
const i::List<ProfileNode*>* top_down_bbb_children =
top_down_root_children->last()->children();
CHECK_EQ(1, top_down_bbb_children->length());
- CHECK_EQ("args_count: 5", top_down_bbb_children->last()->entry()->name());
+ CHECK_EQ("5", top_down_bbb_children->last()->entry()->name());
const i::List<ProfileNode*>* top_down_stub_children =
top_down_bbb_children->last()->children();
CHECK_EQ(1, top_down_stub_children->length());
i::List<ProfileNode*> bottom_up_root_children(3);
bottom_up_root_children.AddAll(*bottom_up_root_children_unsorted);
bottom_up_root_children.Sort(&CompareProfileNodes);
- CHECK_EQ("args_count: 5", bottom_up_root_children[0]->entry()->name());
+ CHECK_EQ("5", bottom_up_root_children[0]->entry()->name());
CHECK_EQ("bbb", bottom_up_root_children[1]->entry()->name());
CHECK_EQ("ddd", bottom_up_root_children[2]->entry()->name());
const i::List<ProfileNode*>* bottom_up_stub_children =
const i::List<ProfileNode*>* bottom_up_ddd_children =
bottom_up_root_children[2]->children();
CHECK_EQ(1, bottom_up_ddd_children->length());
- CHECK_EQ("args_count: 5", bottom_up_ddd_children->last()->entry()->name());
+ CHECK_EQ("5", bottom_up_ddd_children->last()->entry()->name());
const i::List<ProfileNode*>* bottom_up_ddd_stub_children =
bottom_up_ddd_children->last()->children();
CHECK_EQ(1, bottom_up_ddd_stub_children->length());
#include "v8.h"
#include "log.h"
+#include "cpu-profiler.h"
#include "v8threads.h"
#include "cctest.h"
TEST(ProfileNodeFindOrAddChild) {
ProfileNode node(NULL);
- CodeEntry entry1(i::Logger::FUNCTION_TAG, "aaa", "", 0);
+ CodeEntry entry1(i::Logger::FUNCTION_TAG, "", "aaa", "", 0);
ProfileNode* childNode1 = node.FindOrAddChild(&entry1);
CHECK_NE(NULL, childNode1);
CHECK_EQ(childNode1, node.FindOrAddChild(&entry1));
- CodeEntry entry2(i::Logger::FUNCTION_TAG, "bbb", "", 0);
+ CodeEntry entry2(i::Logger::FUNCTION_TAG, "", "bbb", "", 0);
ProfileNode* childNode2 = node.FindOrAddChild(&entry2);
CHECK_NE(NULL, childNode2);
CHECK_NE(childNode1, childNode2);
CHECK_EQ(childNode1, node.FindOrAddChild(&entry1));
CHECK_EQ(childNode2, node.FindOrAddChild(&entry2));
- CodeEntry entry3(i::Logger::FUNCTION_TAG, "ccc", "", 0);
+ CodeEntry entry3(i::Logger::FUNCTION_TAG, "", "ccc", "", 0);
ProfileNode* childNode3 = node.FindOrAddChild(&entry3);
CHECK_NE(NULL, childNode3);
CHECK_NE(childNode1, childNode3);
} // namespace
TEST(ProfileTreeAddPathFromStart) {
- CodeEntry entry1(i::Logger::FUNCTION_TAG, "aaa", "", 0);
- CodeEntry entry2(i::Logger::FUNCTION_TAG, "bbb", "", 0);
- CodeEntry entry3(i::Logger::FUNCTION_TAG, "ccc", "", 0);
+ CodeEntry entry1(i::Logger::FUNCTION_TAG, "", "aaa", "", 0);
+ CodeEntry entry2(i::Logger::FUNCTION_TAG, "", "bbb", "", 0);
+ CodeEntry entry3(i::Logger::FUNCTION_TAG, "", "ccc", "", 0);
ProfileTree tree;
ProfileTreeTestHelper helper(&tree);
CHECK_EQ(NULL, helper.Walk(&entry1));
TEST(ProfileTreeAddPathFromEnd) {
- CodeEntry entry1(i::Logger::FUNCTION_TAG, "aaa", "", 0);
- CodeEntry entry2(i::Logger::FUNCTION_TAG, "bbb", "", 0);
- CodeEntry entry3(i::Logger::FUNCTION_TAG, "ccc", "", 0);
+ CodeEntry entry1(i::Logger::FUNCTION_TAG, "", "aaa", "", 0);
+ CodeEntry entry2(i::Logger::FUNCTION_TAG, "", "bbb", "", 0);
+ CodeEntry entry3(i::Logger::FUNCTION_TAG, "", "ccc", "", 0);
ProfileTree tree;
ProfileTreeTestHelper helper(&tree);
CHECK_EQ(NULL, helper.Walk(&entry1));
CHECK_EQ(1, empty_tree.root()->total_ticks());
CHECK_EQ(1, empty_tree.root()->self_ticks());
- CodeEntry entry1(i::Logger::FUNCTION_TAG, "aaa", "", 0);
- CodeEntry entry2(i::Logger::FUNCTION_TAG, "bbb", "", 0);
+ CodeEntry entry1(i::Logger::FUNCTION_TAG, "", "aaa", "", 0);
+ CodeEntry entry2(i::Logger::FUNCTION_TAG, "", "bbb", "", 0);
CodeEntry* e1_path[] = {&entry1};
Vector<CodeEntry*> e1_path_vec(
e1_path, sizeof(e1_path) / sizeof(e1_path[0]));
CodeEntry* e2_path[] = {&entry2};
Vector<CodeEntry*> e2_path_vec(
e2_path, sizeof(e2_path) / sizeof(e2_path[0]));
- CodeEntry entry3(i::Logger::FUNCTION_TAG, "ccc", "", 0);
+ CodeEntry entry3(i::Logger::FUNCTION_TAG, "", "ccc", "", 0);
CodeEntry* e3_path[] = {&entry3};
Vector<CodeEntry*> e3_path_vec(
e3_path, sizeof(e3_path) / sizeof(e3_path[0]));
TEST(CodeMapAddCode) {
CodeMap code_map;
- CodeEntry entry1(i::Logger::FUNCTION_TAG, "aaa", "", 0);
- CodeEntry entry2(i::Logger::FUNCTION_TAG, "bbb", "", 0);
- CodeEntry entry3(i::Logger::FUNCTION_TAG, "ccc", "", 0);
- CodeEntry entry4(i::Logger::FUNCTION_TAG, "ddd", "", 0);
+ CodeEntry entry1(i::Logger::FUNCTION_TAG, "", "aaa", "", 0);
+ CodeEntry entry2(i::Logger::FUNCTION_TAG, "", "bbb", "", 0);
+ CodeEntry entry3(i::Logger::FUNCTION_TAG, "", "ccc", "", 0);
+ CodeEntry entry4(i::Logger::FUNCTION_TAG, "", "ddd", "", 0);
code_map.AddCode(ToAddress(0x1500), &entry1, 0x200);
code_map.AddCode(ToAddress(0x1700), &entry2, 0x100);
code_map.AddCode(ToAddress(0x1900), &entry3, 0x50);
TEST(CodeMapMoveAndDeleteCode) {
CodeMap code_map;
- CodeEntry entry1(i::Logger::FUNCTION_TAG, "aaa", "", 0);
- CodeEntry entry2(i::Logger::FUNCTION_TAG, "bbb", "", 0);
+ CodeEntry entry1(i::Logger::FUNCTION_TAG, "", "aaa", "", 0);
+ CodeEntry entry2(i::Logger::FUNCTION_TAG, "", "bbb", "", 0);
code_map.AddCode(ToAddress(0x1500), &entry1, 0x200);
code_map.AddCode(ToAddress(0x1700), &entry2, 0x100);
CHECK_EQ(&entry1, code_map.FindEntry(ToAddress(0x1500)));