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 >())
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 true
#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)
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 trace on stack replacement optimize closures functions with arguments object optimize functions containing for in loops profiler considers IC stability primitive functions trigger their own optimization re try self optimization if it failed insert an interrupt check at function exit execution budget before interrupt is triggered call count before self optimization self_optimization count_based_interrupts weighted_back_edges trace_opt 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 enable use of ARMv7 instructions if enable use of MIPS FPU instructions if NULL
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
#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)
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()
static v8::internal::Handle< v8::internal::TemplateInfo > OpenHandle(const Template *that)