Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(167)

Side by Side Diff: test/cctest/test-log-stack-tracer.cc

Issue 23519010: cleanup cctest generally and remove ctest::context (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: arm fix Created 7 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « test/cctest/test-heap.cc ('k') | test/cctest/test-mark-compact.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2011 the V8 project authors. All rights reserved. 1 // Copyright 2011 the V8 project authors. All rights reserved.
2 // Redistribution and use in source and binary forms, with or without 2 // Redistribution and use in source and binary forms, with or without
3 // modification, are permitted provided that the following conditions are 3 // modification, are permitted provided that the following conditions are
4 // met: 4 // met:
5 // 5 //
6 // * Redistributions of source code must retain the above copyright 6 // * Redistributions of source code must retain the above copyright
7 // notice, this list of conditions and the following disclaimer. 7 // notice, this list of conditions and the following disclaimer.
8 // * Redistributions in binary form must reproduce the above 8 // * Redistributions in binary form must reproduce the above
9 // copyright notice, this list of conditions and the following 9 // copyright notice, this list of conditions and the following
10 // disclaimer in the documentation and/or other materials provided 10 // disclaimer in the documentation and/or other materials provided
(...skipping 169 matching lines...) Expand 10 before | Expand all | Expand 10 after
180 static TraceExtension kTraceExtension; 180 static TraceExtension kTraceExtension;
181 v8::DeclareExtension kTraceExtensionDeclaration(&kTraceExtension); 181 v8::DeclareExtension kTraceExtensionDeclaration(&kTraceExtension);
182 182
183 183
184 static bool IsAddressWithinFuncCode(JSFunction* function, Address addr) { 184 static bool IsAddressWithinFuncCode(JSFunction* function, Address addr) {
185 i::Code* code = function->code(); 185 i::Code* code = function->code();
186 return code->contains(addr); 186 return code->contains(addr);
187 } 187 }
188 188
189 189
190 static bool IsAddressWithinFuncCode(const char* func_name, Address addr) { 190 static bool IsAddressWithinFuncCode(v8::Local<v8::Context> context,
191 v8::Local<v8::Value> func = CcTest::env()->Global()->Get(v8_str(func_name)); 191 const char* func_name,
192 Address addr) {
193 v8::Local<v8::Value> func = context->Global()->Get(v8_str(func_name));
192 CHECK(func->IsFunction()); 194 CHECK(func->IsFunction());
193 JSFunction* js_func = JSFunction::cast(*v8::Utils::OpenHandle(*func)); 195 JSFunction* js_func = JSFunction::cast(*v8::Utils::OpenHandle(*func));
194 return IsAddressWithinFuncCode(js_func, addr); 196 return IsAddressWithinFuncCode(js_func, addr);
195 } 197 }
196 198
197 199
198 // This C++ function is called as a constructor, to grab the frame pointer 200 // This C++ function is called as a constructor, to grab the frame pointer
199 // from the calling function. When this function runs, the stack contains 201 // from the calling function. When this function runs, the stack contains
200 // a C_Entry frame and a Construct frame above the calling function's frame. 202 // a C_Entry frame and a Construct frame above the calling function's frame.
201 static void construct_call(const v8::FunctionCallbackInfo<v8::Value>& args) { 203 static void construct_call(const v8::FunctionCallbackInfo<v8::Value>& args) {
(...skipping 16 matching lines...) Expand all
218 args.This()->Set(v8_str("low_bits"), v8_num(low_bits)); 220 args.This()->Set(v8_str("low_bits"), v8_num(low_bits));
219 args.This()->Set(v8_str("high_bits"), v8_num(high_bits)); 221 args.This()->Set(v8_str("high_bits"), v8_num(high_bits));
220 #else 222 #else
221 #error Host architecture is neither 32-bit nor 64-bit. 223 #error Host architecture is neither 32-bit nor 64-bit.
222 #endif 224 #endif
223 args.GetReturnValue().Set(args.This()); 225 args.GetReturnValue().Set(args.This());
224 } 226 }
225 227
226 228
227 // Use the API to create a JSFunction object that calls the above C++ function. 229 // Use the API to create a JSFunction object that calls the above C++ function.
228 void CreateFramePointerGrabberConstructor(const char* constructor_name) { 230 void CreateFramePointerGrabberConstructor(v8::Local<v8::Context> context,
231 const char* constructor_name) {
229 Local<v8::FunctionTemplate> constructor_template = 232 Local<v8::FunctionTemplate> constructor_template =
230 v8::FunctionTemplate::New(construct_call); 233 v8::FunctionTemplate::New(construct_call);
231 constructor_template->SetClassName(v8_str("FPGrabber")); 234 constructor_template->SetClassName(v8_str("FPGrabber"));
232 Local<Function> fun = constructor_template->GetFunction(); 235 Local<Function> fun = constructor_template->GetFunction();
233 CcTest::env()->Global()->Set(v8_str(constructor_name), fun); 236 context->Global()->Set(v8_str(constructor_name), fun);
234 } 237 }
235 238
236 239
237 // Creates a global function named 'func_name' that calls the tracing 240 // Creates a global function named 'func_name' that calls the tracing
238 // function 'trace_func_name' with an actual EBP register value, 241 // function 'trace_func_name' with an actual EBP register value,
239 // encoded as one or two Smis. 242 // encoded as one or two Smis.
240 static void CreateTraceCallerFunction(const char* func_name, 243 static void CreateTraceCallerFunction(v8::Local<v8::Context> context,
244 const char* func_name,
241 const char* trace_func_name) { 245 const char* trace_func_name) {
242 i::EmbeddedVector<char, 256> trace_call_buf; 246 i::EmbeddedVector<char, 256> trace_call_buf;
243 i::OS::SNPrintF(trace_call_buf, 247 i::OS::SNPrintF(trace_call_buf,
244 "function %s() {" 248 "function %s() {"
245 " fp = new FPGrabber();" 249 " fp = new FPGrabber();"
246 " %s(fp.low_bits, fp.high_bits);" 250 " %s(fp.low_bits, fp.high_bits);"
247 "}", 251 "}",
248 func_name, trace_func_name); 252 func_name, trace_func_name);
249 253
250 // Create the FPGrabber function, which grabs the caller's frame pointer 254 // Create the FPGrabber function, which grabs the caller's frame pointer
251 // when called as a constructor. 255 // when called as a constructor.
252 CreateFramePointerGrabberConstructor("FPGrabber"); 256 CreateFramePointerGrabberConstructor(context, "FPGrabber");
253 257
254 // Compile the script. 258 // Compile the script.
255 CompileRun(trace_call_buf.start()); 259 CompileRun(trace_call_buf.start());
256 } 260 }
257 261
258 262
259 // This test verifies that stack tracing works when called during 263 // This test verifies that stack tracing works when called during
260 // execution of a native function called from JS code. In this case, 264 // execution of a native function called from JS code. In this case,
261 // TickSample::Trace uses Isolate::c_entry_fp as a starting point for stack 265 // TickSample::Trace uses Isolate::c_entry_fp as a starting point for stack
262 // walking. 266 // walking.
263 TEST(CFromJSStackTrace) { 267 TEST(CFromJSStackTrace) {
264 // BUG(1303) Inlining of JSFuncDoTrace() in JSTrace below breaks this test. 268 // BUG(1303) Inlining of JSFuncDoTrace() in JSTrace below breaks this test.
265 i::FLAG_use_inlining = false; 269 i::FLAG_use_inlining = false;
266 270
267 TickSample sample; 271 TickSample sample;
268 InitTraceEnv(&sample); 272 InitTraceEnv(&sample);
269 273
270 CcTest::InitializeVM(TRACE_EXTENSION);
271 v8::HandleScope scope(CcTest::isolate()); 274 v8::HandleScope scope(CcTest::isolate());
275 v8::Local<v8::Context> context = CcTest::NewContext(TRACE_EXTENSION);
276 v8::Context::Scope context_scope(context);
277
272 // Create global function JSFuncDoTrace which calls 278 // Create global function JSFuncDoTrace which calls
273 // extension function trace() with the current frame pointer value. 279 // extension function trace() with the current frame pointer value.
274 CreateTraceCallerFunction("JSFuncDoTrace", "trace"); 280 CreateTraceCallerFunction(context, "JSFuncDoTrace", "trace");
275 Local<Value> result = CompileRun( 281 Local<Value> result = CompileRun(
276 "function JSTrace() {" 282 "function JSTrace() {"
277 " JSFuncDoTrace();" 283 " JSFuncDoTrace();"
278 "};\n" 284 "};\n"
279 "JSTrace();\n" 285 "JSTrace();\n"
280 "true;"); 286 "true;");
281 CHECK(!result.IsEmpty()); 287 CHECK(!result.IsEmpty());
282 // When stack tracer is invoked, the stack should look as follows: 288 // When stack tracer is invoked, the stack should look as follows:
283 // script [JS] 289 // script [JS]
284 // JSTrace() [JS] 290 // JSTrace() [JS]
285 // JSFuncDoTrace() [JS] [captures EBP value and encodes it as Smi] 291 // JSFuncDoTrace() [JS] [captures EBP value and encodes it as Smi]
286 // trace(EBP) [native (extension)] 292 // trace(EBP) [native (extension)]
287 // DoTrace(EBP) [native] 293 // DoTrace(EBP) [native]
288 // TickSample::Trace 294 // TickSample::Trace
289 295
290 CHECK(sample.has_external_callback); 296 CHECK(sample.has_external_callback);
291 CHECK_EQ(FUNCTION_ADDR(TraceExtension::Trace), sample.external_callback); 297 CHECK_EQ(FUNCTION_ADDR(TraceExtension::Trace), sample.external_callback);
292 298
293 // Stack tracing will start from the first JS function, i.e. "JSFuncDoTrace" 299 // Stack tracing will start from the first JS function, i.e. "JSFuncDoTrace"
294 int base = 0; 300 int base = 0;
295 CHECK_GT(sample.frames_count, base + 1); 301 CHECK_GT(sample.frames_count, base + 1);
296 302
297 CHECK(IsAddressWithinFuncCode("JSFuncDoTrace", sample.stack[base + 0])); 303 CHECK(IsAddressWithinFuncCode(
298 CHECK(IsAddressWithinFuncCode("JSTrace", sample.stack[base + 1])); 304 context, "JSFuncDoTrace", sample.stack[base + 0]));
305 CHECK(IsAddressWithinFuncCode(context, "JSTrace", sample.stack[base + 1]));
299 } 306 }
300 307
301 308
302 // This test verifies that stack tracing works when called during 309 // This test verifies that stack tracing works when called during
303 // execution of JS code. However, as calling TickSample::Trace requires 310 // execution of JS code. However, as calling TickSample::Trace requires
304 // entering native code, we can only emulate pure JS by erasing 311 // entering native code, we can only emulate pure JS by erasing
305 // Isolate::c_entry_fp value. In this case, TickSample::Trace uses passed frame 312 // Isolate::c_entry_fp value. In this case, TickSample::Trace uses passed frame
306 // pointer value as a starting point for stack walking. 313 // pointer value as a starting point for stack walking.
307 TEST(PureJSStackTrace) { 314 TEST(PureJSStackTrace) {
308 // This test does not pass with inlining enabled since inlined functions 315 // This test does not pass with inlining enabled since inlined functions
309 // don't appear in the stack trace. 316 // don't appear in the stack trace.
310 i::FLAG_use_inlining = false; 317 i::FLAG_use_inlining = false;
311 318
312 TickSample sample; 319 TickSample sample;
313 InitTraceEnv(&sample); 320 InitTraceEnv(&sample);
314 321
315 CcTest::InitializeVM(TRACE_EXTENSION);
316 v8::HandleScope scope(CcTest::isolate()); 322 v8::HandleScope scope(CcTest::isolate());
323 v8::Local<v8::Context> context = CcTest::NewContext(TRACE_EXTENSION);
324 v8::Context::Scope context_scope(context);
325
317 // Create global function JSFuncDoTrace which calls 326 // Create global function JSFuncDoTrace which calls
318 // extension function js_trace() with the current frame pointer value. 327 // extension function js_trace() with the current frame pointer value.
319 CreateTraceCallerFunction("JSFuncDoTrace", "js_trace"); 328 CreateTraceCallerFunction(context, "JSFuncDoTrace", "js_trace");
320 Local<Value> result = CompileRun( 329 Local<Value> result = CompileRun(
321 "function JSTrace() {" 330 "function JSTrace() {"
322 " JSFuncDoTrace();" 331 " JSFuncDoTrace();"
323 "};\n" 332 "};\n"
324 "function OuterJSTrace() {" 333 "function OuterJSTrace() {"
325 " JSTrace();" 334 " JSTrace();"
326 "};\n" 335 "};\n"
327 "OuterJSTrace();\n" 336 "OuterJSTrace();\n"
328 "true;"); 337 "true;");
329 CHECK(!result.IsEmpty()); 338 CHECK(!result.IsEmpty());
330 // When stack tracer is invoked, the stack should look as follows: 339 // When stack tracer is invoked, the stack should look as follows:
331 // script [JS] 340 // script [JS]
332 // OuterJSTrace() [JS] 341 // OuterJSTrace() [JS]
333 // JSTrace() [JS] 342 // JSTrace() [JS]
334 // JSFuncDoTrace() [JS] 343 // JSFuncDoTrace() [JS]
335 // js_trace(EBP) [native (extension)] 344 // js_trace(EBP) [native (extension)]
336 // DoTraceHideCEntryFPAddress(EBP) [native] 345 // DoTraceHideCEntryFPAddress(EBP) [native]
337 // TickSample::Trace 346 // TickSample::Trace
338 // 347 //
339 348
340 CHECK(sample.has_external_callback); 349 CHECK(sample.has_external_callback);
341 CHECK_EQ(FUNCTION_ADDR(TraceExtension::JSTrace), sample.external_callback); 350 CHECK_EQ(FUNCTION_ADDR(TraceExtension::JSTrace), sample.external_callback);
342 351
343 // Stack sampling will start from the caller of JSFuncDoTrace, i.e. "JSTrace" 352 // Stack sampling will start from the caller of JSFuncDoTrace, i.e. "JSTrace"
344 int base = 0; 353 int base = 0;
345 CHECK_GT(sample.frames_count, base + 1); 354 CHECK_GT(sample.frames_count, base + 1);
346 CHECK(IsAddressWithinFuncCode("JSTrace", sample.stack[base + 0])); 355 CHECK(IsAddressWithinFuncCode(context, "JSTrace", sample.stack[base + 0]));
347 CHECK(IsAddressWithinFuncCode("OuterJSTrace", sample.stack[base + 1])); 356 CHECK(IsAddressWithinFuncCode(
357 context, "OuterJSTrace", sample.stack[base + 1]));
348 } 358 }
349 359
350 360
351 static void CFuncDoTrace(byte dummy_parameter) { 361 static void CFuncDoTrace(byte dummy_parameter) {
352 Address fp; 362 Address fp;
353 #ifdef __GNUC__ 363 #ifdef __GNUC__
354 fp = reinterpret_cast<Address>(__builtin_frame_address(0)); 364 fp = reinterpret_cast<Address>(__builtin_frame_address(0));
355 #elif defined _MSC_VER 365 #elif defined _MSC_VER
356 // Approximate a frame pointer address. We compile without base pointers, 366 // Approximate a frame pointer address. We compile without base pointers,
357 // so we can't trust ebp/rbp. 367 // so we can't trust ebp/rbp.
(...skipping 14 matching lines...) Expand all
372 } 382 }
373 } 383 }
374 384
375 385
376 // This test verifies that stack tracing doesn't crash when called on 386 // This test verifies that stack tracing doesn't crash when called on
377 // pure native code. TickSample::Trace only unrolls JS code, so we can't 387 // pure native code. TickSample::Trace only unrolls JS code, so we can't
378 // get any meaningful info here. 388 // get any meaningful info here.
379 TEST(PureCStackTrace) { 389 TEST(PureCStackTrace) {
380 TickSample sample; 390 TickSample sample;
381 InitTraceEnv(&sample); 391 InitTraceEnv(&sample);
382 CcTest::InitializeVM(TRACE_EXTENSION); 392 v8::HandleScope scope(CcTest::isolate());
393 v8::Local<v8::Context> context = CcTest::NewContext(TRACE_EXTENSION);
394 v8::Context::Scope context_scope(context);
383 // Check that sampler doesn't crash 395 // Check that sampler doesn't crash
384 CHECK_EQ(10, CFunc(10)); 396 CHECK_EQ(10, CFunc(10));
385 } 397 }
386 398
387 399
388 TEST(JsEntrySp) { 400 TEST(JsEntrySp) {
389 CcTest::InitializeVM(TRACE_EXTENSION);
390 v8::HandleScope scope(CcTest::isolate()); 401 v8::HandleScope scope(CcTest::isolate());
402 v8::Local<v8::Context> context = CcTest::NewContext(TRACE_EXTENSION);
403 v8::Context::Scope context_scope(context);
391 CHECK_EQ(0, GetJsEntrySp()); 404 CHECK_EQ(0, GetJsEntrySp());
392 CompileRun("a = 1; b = a + 1;"); 405 CompileRun("a = 1; b = a + 1;");
393 CHECK_EQ(0, GetJsEntrySp()); 406 CHECK_EQ(0, GetJsEntrySp());
394 CompileRun("js_entry_sp();"); 407 CompileRun("js_entry_sp();");
395 CHECK_EQ(0, GetJsEntrySp()); 408 CHECK_EQ(0, GetJsEntrySp());
396 CompileRun("js_entry_sp_level2();"); 409 CompileRun("js_entry_sp_level2();");
397 CHECK_EQ(0, GetJsEntrySp()); 410 CHECK_EQ(0, GetJsEntrySp());
398 } 411 }
OLDNEW
« no previous file with comments | « test/cctest/test-heap.cc ('k') | test/cctest/test-mark-compact.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698