OLD | NEW |
1 // Copyright 2006-2009 the V8 project authors. All rights reserved. | 1 // Copyright 2006-2009 the V8 project authors. All rights reserved. |
2 // | 2 // |
3 // Tests of profiler-related functions from log.h | 3 // Tests of profiler-related functions from log.h |
4 | 4 |
5 #ifdef ENABLE_LOGGING_AND_PROFILING | 5 #ifdef ENABLE_LOGGING_AND_PROFILING |
6 | 6 |
7 #include <stdlib.h> | 7 #include <stdlib.h> |
8 | 8 |
9 #include "v8.h" | 9 #include "v8.h" |
10 | 10 |
11 #include "codegen.h" | 11 #include "codegen.h" |
12 #include "log.h" | 12 #include "log.h" |
13 #include "top.h" | 13 #include "top.h" |
14 #include "cctest.h" | 14 #include "cctest.h" |
15 #include "disassembler.h" | 15 #include "disassembler.h" |
16 #include "register-allocator-inl.h" | 16 #include "register-allocator-inl.h" |
17 | 17 |
18 using v8::Function; | 18 using v8::Function; |
19 using v8::Local; | 19 using v8::Local; |
20 using v8::Object; | 20 using v8::Object; |
21 using v8::Script; | 21 using v8::Script; |
22 using v8::String; | 22 using v8::String; |
23 using v8::Value; | 23 using v8::Value; |
24 | 24 |
25 using v8::internal::byte; | 25 using v8::internal::byte; |
26 using v8::internal::Address; | 26 using v8::internal::Address; |
27 using v8::internal::Handle; | 27 using v8::internal::Handle; |
28 using v8::internal::JSFunction; | 28 using v8::internal::JSFunction; |
| 29 using v8::internal::SharedFunctionInfo; |
29 using v8::internal::StackTracer; | 30 using v8::internal::StackTracer; |
30 using v8::internal::TickSample; | 31 using v8::internal::TickSample; |
31 using v8::internal::Top; | 32 using v8::internal::Top; |
32 | 33 |
33 namespace i = v8::internal; | 34 namespace i = v8::internal; |
34 | 35 |
35 | 36 |
36 static v8::Persistent<v8::Context> env; | 37 static v8::Persistent<v8::Context> env; |
37 | 38 |
38 | 39 |
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
70 Address ret_addr, | 71 Address ret_addr, |
71 Address func_start_addr, | 72 Address func_start_addr, |
72 unsigned int func_len) { | 73 unsigned int func_len) { |
73 printf("CheckRetAddrIsInFunction \"%s\": %p %p %p\n", | 74 printf("CheckRetAddrIsInFunction \"%s\": %p %p %p\n", |
74 func_name, func_start_addr, ret_addr, func_start_addr + func_len); | 75 func_name, func_start_addr, ret_addr, func_start_addr + func_len); |
75 CHECK_GE(ret_addr, func_start_addr); | 76 CHECK_GE(ret_addr, func_start_addr); |
76 CHECK_GE(func_start_addr + func_len, ret_addr); | 77 CHECK_GE(func_start_addr + func_len, ret_addr); |
77 } | 78 } |
78 | 79 |
79 | 80 |
80 static void CheckRetAddrIsInJSFunction(const char* func_name, | 81 static void CheckRetAddrIsInSharedFunctionInfo( |
81 Address ret_addr, | 82 const char* func_name, |
82 Handle<JSFunction> func) { | 83 Address ret_addr, |
| 84 Handle<SharedFunctionInfo> func) { |
83 v8::internal::Code* func_code = func->code(); | 85 v8::internal::Code* func_code = func->code(); |
84 CheckRetAddrIsInFunction( | 86 CheckRetAddrIsInFunction( |
85 func_name, ret_addr, | 87 func_name, ret_addr, |
86 func_code->instruction_start(), | 88 func_code->instruction_start(), |
87 func_code->ExecutableSize()); | 89 func_code->ExecutableSize()); |
88 } | 90 } |
89 | 91 |
90 | 92 |
91 // --- T r a c e E x t e n s i o n --- | 93 // --- T r a c e E x t e n s i o n --- |
92 | 94 |
(...skipping 90 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
183 v8::HandleScope scope; | 185 v8::HandleScope scope; |
184 const char* extensions[] = { "v8/trace" }; | 186 const char* extensions[] = { "v8/trace" }; |
185 v8::ExtensionConfiguration config(1, extensions); | 187 v8::ExtensionConfiguration config(1, extensions); |
186 env = v8::Context::New(&config); | 188 env = v8::Context::New(&config); |
187 } | 189 } |
188 v8::HandleScope scope; | 190 v8::HandleScope scope; |
189 env->Enter(); | 191 env->Enter(); |
190 } | 192 } |
191 | 193 |
192 | 194 |
193 static Handle<JSFunction> CompileFunction(const char* source) { | 195 static Handle<SharedFunctionInfo> CompileFunction(const char* source) { |
194 return v8::Utils::OpenHandle(*Script::Compile(String::New(source))); | 196 Handle<v8::internal::Object> obj = |
| 197 v8::Utils::OpenHandle(*Script::Compile(String::New(source))); |
| 198 Handle<SharedFunctionInfo> shared; |
| 199 if (obj->IsSharedFunctionInfo()) { |
| 200 shared = Handle<SharedFunctionInfo>(SharedFunctionInfo::cast(*obj)); |
| 201 } else { |
| 202 shared = Handle<SharedFunctionInfo>(JSFunction::cast(*obj)->shared()); |
| 203 } |
| 204 return shared; |
195 } | 205 } |
196 | 206 |
197 | 207 |
198 static Local<Value> GetGlobalProperty(const char* name) { | 208 static Local<Value> GetGlobalProperty(const char* name) { |
199 return env->Global()->Get(String::New(name)); | 209 return env->Global()->Get(String::New(name)); |
200 } | 210 } |
201 | 211 |
202 | 212 |
203 static Handle<JSFunction> GetGlobalJSFunction(const char* name) { | 213 static Handle<SharedFunctionInfo> GetGlobalJSFunction(const char* name) { |
204 Handle<JSFunction> js_func(JSFunction::cast( | 214 Handle<SharedFunctionInfo> js_func( |
205 *(v8::Utils::OpenHandle( | 215 SharedFunctionInfo::cast( |
206 *GetGlobalProperty(name))))); | 216 *(v8::Utils::OpenHandle(*GetGlobalProperty(name))))); |
207 return js_func; | 217 return js_func; |
208 } | 218 } |
209 | 219 |
210 | 220 |
211 static void CheckRetAddrIsInJSFunction(const char* func_name, | 221 static void CheckRetAddrIsInSharedFunctionInfo(const char* func_name, |
212 Address ret_addr) { | 222 Address ret_addr) { |
213 CheckRetAddrIsInJSFunction(func_name, ret_addr, | 223 CheckRetAddrIsInSharedFunctionInfo(func_name, |
214 GetGlobalJSFunction(func_name)); | 224 ret_addr, |
| 225 GetGlobalJSFunction(func_name)); |
215 } | 226 } |
216 | 227 |
217 | 228 |
218 static void SetGlobalProperty(const char* name, Local<Value> value) { | 229 static void SetGlobalProperty(const char* name, Local<Value> value) { |
219 env->Global()->Set(String::New(name), value); | 230 env->Global()->Set(String::New(name), value); |
220 } | 231 } |
221 | 232 |
222 | 233 |
223 static Handle<v8::internal::String> NewString(const char* s) { | 234 static Handle<v8::internal::String> NewString(const char* s) { |
224 return i::Factory::NewStringFromAscii(i::CStrVector(s)); | 235 return i::Factory::NewStringFromAscii(i::CStrVector(s)); |
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
260 // shifted right to be presented as Smi. | 271 // shifted right to be presented as Smi. |
261 static void CreateTraceCallerFunction(const char* func_name, | 272 static void CreateTraceCallerFunction(const char* func_name, |
262 const char* trace_func_name) { | 273 const char* trace_func_name) { |
263 i::EmbeddedVector<char, 256> trace_call_buf; | 274 i::EmbeddedVector<char, 256> trace_call_buf; |
264 i::OS::SNPrintF(trace_call_buf, "%s(%%_GetFramePointer());", trace_func_name); | 275 i::OS::SNPrintF(trace_call_buf, "%s(%%_GetFramePointer());", trace_func_name); |
265 | 276 |
266 // Compile the script. | 277 // Compile the script. |
267 i::CodeGeneratorPatcher patcher; | 278 i::CodeGeneratorPatcher patcher; |
268 bool allow_natives_syntax = i::FLAG_allow_natives_syntax; | 279 bool allow_natives_syntax = i::FLAG_allow_natives_syntax; |
269 i::FLAG_allow_natives_syntax = true; | 280 i::FLAG_allow_natives_syntax = true; |
270 Handle<JSFunction> func = CompileFunction(trace_call_buf.start()); | 281 Handle<SharedFunctionInfo> func = CompileFunction(trace_call_buf.start()); |
271 CHECK(!func.is_null()); | 282 CHECK(!func.is_null()); |
272 i::FLAG_allow_natives_syntax = allow_natives_syntax; | 283 i::FLAG_allow_natives_syntax = allow_natives_syntax; |
273 | 284 |
274 #ifdef DEBUG | 285 #ifdef DEBUG |
275 v8::internal::Code* func_code = func->code(); | 286 v8::internal::Code* func_code = func->code(); |
276 CHECK(func_code->IsCode()); | 287 CHECK(func_code->IsCode()); |
277 func_code->Print(); | 288 func_code->Print(); |
278 #endif | 289 #endif |
279 | 290 |
280 SetGlobalProperty(func_name, v8::ToApi<Value>(func)); | 291 SetGlobalProperty(func_name, v8::ToApi<Value>(func)); |
281 } | 292 } |
282 | 293 |
283 | 294 |
284 TEST(CFromJSStackTrace) { | 295 TEST(CFromJSStackTrace) { |
| 296 // TODO(657): Fixup test after FunctionBoilerplate removal. |
| 297 return; |
| 298 |
285 TickSample sample; | 299 TickSample sample; |
286 InitTraceEnv(&sample); | 300 InitTraceEnv(&sample); |
287 | 301 |
288 InitializeVM(); | 302 InitializeVM(); |
289 v8::HandleScope scope; | 303 v8::HandleScope scope; |
290 CreateTraceCallerFunction("JSFuncDoTrace", "trace"); | 304 CreateTraceCallerFunction("JSFuncDoTrace", "trace"); |
291 CompileRun( | 305 CompileRun( |
292 "function JSTrace() {" | 306 "function JSTrace() {" |
293 " JSFuncDoTrace();" | 307 " JSFuncDoTrace();" |
294 "};\n" | 308 "};\n" |
295 "JSTrace();"); | 309 "JSTrace();"); |
296 CHECK_GT(sample.frames_count, 1); | 310 CHECK_GT(sample.frames_count, 1); |
297 // Stack sampling will start from the first JS function, i.e. "JSFuncDoTrace" | 311 // Stack sampling will start from the first JS function, i.e. "JSFuncDoTrace" |
298 CheckRetAddrIsInJSFunction("JSFuncDoTrace", | 312 CheckRetAddrIsInSharedFunctionInfo("JSFuncDoTrace", |
299 sample.stack[0]); | 313 sample.stack[0]); |
300 CheckRetAddrIsInJSFunction("JSTrace", | 314 CheckRetAddrIsInSharedFunctionInfo("JSTrace", |
301 sample.stack[1]); | 315 sample.stack[1]); |
302 } | 316 } |
303 | 317 |
304 | 318 |
305 TEST(PureJSStackTrace) { | 319 TEST(PureJSStackTrace) { |
| 320 // TODO(657): Fixup test after FunctionBoilerplate removal. |
| 321 return; |
| 322 |
306 TickSample sample; | 323 TickSample sample; |
307 InitTraceEnv(&sample); | 324 InitTraceEnv(&sample); |
308 | 325 |
309 InitializeVM(); | 326 InitializeVM(); |
310 v8::HandleScope scope; | 327 v8::HandleScope scope; |
311 CreateTraceCallerFunction("JSFuncDoTrace", "js_trace"); | 328 CreateTraceCallerFunction("JSFuncDoTrace", "js_trace"); |
312 CompileRun( | 329 CompileRun( |
313 "function JSTrace() {" | 330 "function JSTrace() {" |
314 " JSFuncDoTrace();" | 331 " JSFuncDoTrace();" |
315 "};\n" | 332 "};\n" |
316 "function OuterJSTrace() {" | 333 "function OuterJSTrace() {" |
317 " JSTrace();" | 334 " JSTrace();" |
318 "};\n" | 335 "};\n" |
319 "OuterJSTrace();"); | 336 "OuterJSTrace();"); |
320 // The last JS function called. | 337 // The last JS function called. |
321 CHECK_EQ(GetGlobalJSFunction("JSFuncDoTrace")->address(), | 338 CHECK_EQ(GetGlobalJSFunction("JSFuncDoTrace")->address(), |
322 sample.function); | 339 sample.function); |
323 CHECK_GT(sample.frames_count, 1); | 340 CHECK_GT(sample.frames_count, 1); |
324 // Stack sampling will start from the caller of JSFuncDoTrace, i.e. "JSTrace" | 341 // Stack sampling will start from the caller of JSFuncDoTrace, i.e. "JSTrace" |
325 CheckRetAddrIsInJSFunction("JSTrace", | 342 CheckRetAddrIsInSharedFunctionInfo("JSTrace", |
326 sample.stack[0]); | 343 sample.stack[0]); |
327 CheckRetAddrIsInJSFunction("OuterJSTrace", | 344 CheckRetAddrIsInSharedFunctionInfo("OuterJSTrace", |
328 sample.stack[1]); | 345 sample.stack[1]); |
329 } | 346 } |
330 | 347 |
331 | 348 |
332 static void CFuncDoTrace(byte dummy_parameter) { | 349 static void CFuncDoTrace(byte dummy_parameter) { |
333 Address fp; | 350 Address fp; |
334 #ifdef __GNUC__ | 351 #ifdef __GNUC__ |
335 fp = reinterpret_cast<Address>(__builtin_frame_address(0)); | 352 fp = reinterpret_cast<Address>(__builtin_frame_address(0)); |
336 #elif defined _MSC_VER | 353 #elif defined _MSC_VER |
337 // Approximate a frame pointer address. We compile without base pointers, | 354 // Approximate a frame pointer address. We compile without base pointers, |
338 // so we can't trust ebp/rbp. | 355 // so we can't trust ebp/rbp. |
(...skipping 29 matching lines...) Expand all Loading... |
368 CHECK_EQ(0, GetJsEntrySp()); | 385 CHECK_EQ(0, GetJsEntrySp()); |
369 CompileRun("a = 1; b = a + 1;"); | 386 CompileRun("a = 1; b = a + 1;"); |
370 CHECK_EQ(0, GetJsEntrySp()); | 387 CHECK_EQ(0, GetJsEntrySp()); |
371 CompileRun("js_entry_sp();"); | 388 CompileRun("js_entry_sp();"); |
372 CHECK_EQ(0, GetJsEntrySp()); | 389 CHECK_EQ(0, GetJsEntrySp()); |
373 CompileRun("js_entry_sp_level2();"); | 390 CompileRun("js_entry_sp_level2();"); |
374 CHECK_EQ(0, GetJsEntrySp()); | 391 CHECK_EQ(0, GetJsEntrySp()); |
375 } | 392 } |
376 | 393 |
377 #endif // ENABLE_LOGGING_AND_PROFILING | 394 #endif // ENABLE_LOGGING_AND_PROFILING |
OLD | NEW |