29 class ScopedLoggerInitializer {
31 explicit ScopedLoggerInitializer(
bool prof_lazy)
32 : saved_log_(i::FLAG_log),
33 saved_prof_lazy_(i::FLAG_prof_lazy),
34 saved_prof_(i::FLAG_prof),
35 saved_prof_auto_(i::FLAG_prof_auto),
38 trick_to_run_init_flags_(init_flags_(prof_lazy)),
40 env_(v8::Context::New()) {
44 ~ScopedLoggerInitializer() {
47 if (temp_file_ !=
NULL) fclose(temp_file_);
48 i::FLAG_prof_lazy = saved_prof_lazy_;
49 i::FLAG_prof = saved_prof_;
50 i::FLAG_prof_auto = saved_prof_auto_;
51 i::FLAG_log = saved_log_;
56 FILE* StopLoggingGetTempFile() {
57 temp_file_ =
LOGGER->TearDown();
65 static bool init_flags_(
bool prof_lazy) {
68 i::FLAG_prof_lazy = prof_lazy;
69 i::FLAG_prof_auto =
false;
74 const bool saved_log_;
75 const bool saved_prof_lazy_;
76 const bool saved_prof_;
77 const bool saved_prof_auto_;
79 const bool trick_to_run_init_flags_;
89 static const char* StrNStr(
const char*
s1,
const char*
s2,
int n) {
90 if (s1[n] ==
'\0')
return strstr(s1, s2);
94 char* found = strstr(str.start(),
s2);
95 return found !=
NULL ? s1 + (found - str.start()) :
NULL;
100 ScopedLoggerInitializer initialize_logger(
true);
104 LOGGER->StringEvent(
"test-start",
"");
105 CompileRun(
"var a = (function(x) { return x + 1; })(10);");
106 LOGGER->StringEvent(
"test-profiler-start",
"");
109 "var b = (function(x) { return x + 2; })(10);\n"
110 "var c = (function(x) { return x + 3; })(10);\n"
111 "var d = (function(x) { return x + 4; })(10);\n"
112 "var e = (function(x) { return x + 5; })(10);");
114 LOGGER->StringEvent(
"test-profiler-stop",
"");
115 CompileRun(
"var f = (function(x) { return x + 6; })(10);");
117 LOGGER->StringEvent(
"test-profiler-start-2",
"");
120 "var g = (function(x) { return x + 7; })(10);\n"
121 "var h = (function(x) { return x + 8; })(10);\n"
122 "var i = (function(x) { return x + 9; })(10);\n"
123 "var j = (function(x) { return x + 10; })(10);");
125 LOGGER->StringEvent(
"test-profiler-stop-2",
"");
126 LOGGER->StringEvent(
"test-stop",
"");
130 i::ReadFile(initialize_logger.StopLoggingGetTempFile(), &exists,
true));
133 const char* test_start_position =
136 const char* test_profiler_start_position =
137 StrNStr(log.
start(),
"test-profiler-start,", log.
length());
139 CHECK_GT(test_profiler_start_position, test_start_position);
140 const char* test_profiler_stop_position =
141 StrNStr(log.
start(),
"test-profiler-stop,", log.
length());
143 CHECK_GT(test_profiler_stop_position, test_profiler_start_position);
144 const char* test_profiler_start_2_position =
145 StrNStr(log.
start(),
"test-profiler-start-2,", log.
length());
147 CHECK_GT(test_profiler_start_2_position, test_profiler_stop_position);
152 static_cast<int>(test_profiler_start_position -
153 test_start_position)));
157 static_cast<int>(test_profiler_start_2_position -
158 test_profiler_stop_position)));
170 : v8::internal::
Thread(isolate),
171 semaphore_(v8::internal::OS::CreateSemaphore(0)),
178 self_ = pthread_self();
182 void SendSigProf() { pthread_kill(self_, SIGPROF); }
184 void Stop() { run_ =
false; }
186 bool WaitForRunning() {
return semaphore_->Wait(1000000); }
189 bool IsRunning() {
return run_; }
191 virtual void RunLoop() = 0;
193 void SetV8ThreadId() {
197 void SignalRunning() { semaphore_->Signal(); }
214 CHECK_GT(i::Isolate::Current()->thread_manager()->CurrentId(), 0);
216 while (IsRunning()) {
224 "var j; for (var i=0; i<10000; ++i) { j = Math.sin(i); }");
242 CHECK_GT(i::Isolate::Current()->thread_manager()->CurrentId(), 0);
245 while (IsRunning()) {
257 semaphore_(v8::internal::OS::CreateSemaphore(0)),
258 was_sample_stack_called_(
false) {
261 ~TestSampler() {
delete semaphore_; }
264 was_sample_stack_called_ =
true;
269 bool WaitForTick() {
return semaphore_->Wait(1000000); }
271 void Reset() { was_sample_stack_called_ =
false; }
273 bool WasSampleStackCalled() {
return was_sample_stack_called_; }
277 bool was_sample_stack_called_;
283 TEST(ProfMultipleThreads) {
284 TestSampler* sampler =
NULL;
287 sampler =
new TestSampler(v8::internal::Isolate::Current());
289 CHECK(sampler->IsActive());
292 LoopingJsThread jsThread(v8::internal::Isolate::Current());
294 LoopingNonJsThread nonJsThread(v8::internal::Isolate::Current());
297 CHECK(!sampler->WasSampleStackCalled());
298 jsThread.WaitForRunning();
299 jsThread.SendSigProf();
300 CHECK(sampler->WaitForTick());
301 CHECK(sampler->WasSampleStackCalled());
303 CHECK(!sampler->WasSampleStackCalled());
304 nonJsThread.WaitForRunning();
305 nonJsThread.SendSigProf();
306 CHECK(!sampler->WaitForTick());
307 CHECK(!sampler->WasSampleStackCalled());
328 explicit SimpleExternalString(
const char* source)
330 for (
int i = 0; i < utf_source_.length(); ++i)
331 utf_source_[i] = source[i];
333 virtual ~SimpleExternalString() {}
334 virtual size_t length()
const {
return utf_source_.length(); }
335 virtual const uint16_t*
data()
const {
return utf_source_.start(); }
347 SimpleExternalString source_ext_str(
"(function ext() {})();");
353 CHECK(!evil_script->
Run().IsEmpty());
358 i_source->set_resource(
NULL);
361 LOGGER->LogCompiledFunctions();
370 ScopedLoggerInitializer initialize_logger(
false);
377 proto->
Set(v8_str(
"method1"),
383 initialize_logger.env()->Global()->Set(v8_str(
"Obj"), obj->
GetFunction());
384 CompileRun(
"Obj.prototype.method1.toString();");
386 LOGGER->LogCompiledFunctions();
390 i::ReadFile(initialize_logger.StopLoggingGetTempFile(), &exists,
true));
395 "code-creation,Callback,0x%" V8PRIxPTR ",1,\"method1\"\0",
420 ScopedLoggerInitializer initialize_logger(
false);
426 inst->
SetAccessor(v8_str(
"prop1"), Prop1Getter, Prop1Setter);
429 LOGGER->LogAccessorCallbacks();
433 i::ReadFile(initialize_logger.StopLoggingGetTempFile(), &exists,
true));
438 "code-creation,Callback,0x%" V8PRIxPTR ",1,\"get prop1\"",
445 "code-creation,Callback,0x%" V8PRIxPTR ",1,\"set prop1\"",
452 "code-creation,Callback,0x%" V8PRIxPTR ",1,\"get prop2\"",
462 ScopedLoggerInitializer initialize_logger(
false);
477 TEST(EquivalenceOfLoggingAndTraversal) {
488 ScopedLoggerInitializer initialize_logger(
false);
492 "(function f(obj) {\n"
494 " (function a(j) { return function b() { return j; } })(100);\n"
498 LOGGER->StringEvent(
"test-logging-done",
"");
501 LOGGER->LogCompiledFunctions();
502 LOGGER->StringEvent(
"test-traversal-done",
"");
506 i::ReadFile(initialize_logger.StopLoggingGetTempFile(), &exists,
true));
509 initialize_logger.env()->Global()->Set(v8_str(
"_log"), log_str);
513 reinterpret_cast<const char*>(source.
start()), source.
length());
518 printf(
"compile: %s\n", *exception);
524 printf(
"run: %s\n", *exception);
533 printf(
"%s\n", data.start());
V8EXPORT int Length() const
static Local< Script > Compile(Handle< String > source, ScriptOrigin *origin=NULL, ScriptData *pre_data=NULL, Handle< String > script_data=Handle< String >())
#define CHECK_EQ(expected, value)
V8EXPORT bool IsTrue() const
static Local< FunctionTemplate > New(InvocationCallback callback=0, Handle< Value > data=Handle< Value >(), Handle< Signature > signature=Handle< Signature >())
Thread(const Options &options)
static bool UseCrankshaft()
static const char *const kLogToTemporaryFile
static V8EXPORT Local< String > New(const char *data, int length=-1)
static ExternalTwoByteString * cast(Object *obj)
Local< ObjectTemplate > InstanceTemplate()
static Vector< const byte > GetScriptsSource()
i::NativesCollection< i::TEST > TestSources
V8EXPORT Local< String > ToString() const
void Set(Handle< String > name, Handle< Data > value, PropertyAttribute attributes=None)
virtual const uint16_t * data() const =0
void SetClassName(Handle< String > name)
virtual size_t length() const =0
Vector< const char > ReadFile(const char *filename, bool *exists, bool verbose)
void SetAccessor(Handle< String > name, AccessorGetter getter, AccessorSetter setter=0, Handle< Value > data=Handle< Value >(), AccessControl settings=DEFAULT, PropertyAttribute attribute=None, Handle< AccessorSignature > signature=Handle< AccessorSignature >())
static void ResumeProfiler()
#define DISALLOW_COPY_AND_ASSIGN(TypeName)
static Persistent< T > New(Handle< T > that)
static const int kMakeHeapIterableMask
activate correct semantics for inheriting readonliness false
#define CHECK_NE(unexpected, value)
static void Sleep(const int milliseconds)
int StrLength(const char *string)
static int SNPrintF(Vector< char > str, const char *format,...)
Local< Function > GetFunction()
static int GetCurrentThreadId()
void SampleStack(TickSample *sample)
Local< ObjectTemplate > PrototypeTemplate()
static Local< Signature > New(Handle< FunctionTemplate > receiver=Handle< FunctionTemplate >(), int argc=0, Handle< FunctionTemplate > argv[]=0)
activate correct semantics for inheriting readonliness enable harmony semantics for typeof enable harmony enable harmony proxies enable all harmony harmony_scoping harmony_proxies harmony_scoping tracks arrays with only smi values automatically unbox arrays of doubles use crankshaft use hydrogen range analysis use hydrogen global value numbering use function inlining maximum number of AST nodes considered for a single inlining loop invariant code motion print statistics for hydrogen trace generated IR for specified phases trace register allocator trace range analysis trace representation types environment for every instruction put a break point before deoptimizing polymorphic inlining perform array bounds checks elimination use dead code elimination trace on stack replacement optimize closures cache optimized code for closures functions with arguments object loop weight for representation inference allow uint32 values on optimize frames if they are used only in safe operations track parallel recompilation enable all profiler experiments number of stack frames inspected by the profiler call recompile stub directly when self optimizing trigger profiler ticks based on counting instead of timing weight back edges by jump distance for interrupt triggering percentage of ICs that must have type info to allow optimization watch_ic_patching retry_self_opt interrupt_at_exit extra verbose compilation tracing generate extra emit comments in code disassembly enable use of SSE3 instructions if available enable use of CMOV instruction if available enable use of SAHF instruction if enable use of VFP3 instructions if available this implies enabling ARMv7 and VFP2 enable use of VFP2 instructions if available enable use of SDIV and UDIV instructions if enable loading bit constant by means of movw movt instruction enable unaligned accesses for enable use of MIPS FPU instructions if NULL
static void StrNCpy(Vector< char > dest, const char *src, size_t n)
V8EXPORT int WriteAscii(char *buffer, int start=0, int length=-1, int options=NO_OPTIONS) const
static Persistent< Context > New(ExtensionConfiguration *extensions=NULL, Handle< ObjectTemplate > global_template=Handle< ObjectTemplate >(), Handle< Value > global_object=Handle< Value >())
virtual void Tick(TickSample *sample)=0
static V8EXPORT Local< String > NewExternal(ExternalStringResource *resource)
static void PauseProfiler()