| OLD | NEW |
| 1 // Copyright 2010 the V8 project authors. All rights reserved. | 1 // Copyright 2010 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 181 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 192 v8::HandleScope scope; | 192 v8::HandleScope scope; |
| 193 const char* extensions[] = { "v8/trace" }; | 193 const char* extensions[] = { "v8/trace" }; |
| 194 v8::ExtensionConfiguration config(1, extensions); | 194 v8::ExtensionConfiguration config(1, extensions); |
| 195 env = v8::Context::New(&config); | 195 env = v8::Context::New(&config); |
| 196 } | 196 } |
| 197 v8::HandleScope scope; | 197 v8::HandleScope scope; |
| 198 env->Enter(); | 198 env->Enter(); |
| 199 } | 199 } |
| 200 | 200 |
| 201 | 201 |
| 202 static Handle<JSFunction> CompileFunction(const char* source) { | |
| 203 Handle<JSFunction> result(JSFunction::cast( | |
| 204 *v8::Utils::OpenHandle(*Script::Compile(String::New(source))))); | |
| 205 return result; | |
| 206 } | |
| 207 | |
| 208 | |
| 209 static void CheckJSFunctionAtAddress(const char* func_name, Address addr) { | 202 static void CheckJSFunctionAtAddress(const char* func_name, Address addr) { |
| 210 i::Object* obj = i::HeapObject::FromAddress(addr); | 203 i::Object* obj = i::HeapObject::FromAddress(addr); |
| 211 CHECK(obj->IsJSFunction()); | 204 CHECK(obj->IsJSFunction()); |
| 212 CHECK(JSFunction::cast(obj)->shared()->name()->IsString()); | 205 CHECK(JSFunction::cast(obj)->shared()->name()->IsString()); |
| 213 i::SmartPointer<char> found_name = | 206 i::SmartPointer<char> found_name = |
| 214 i::String::cast( | 207 i::String::cast( |
| 215 JSFunction::cast( | 208 JSFunction::cast( |
| 216 obj)->shared()->name())->ToCString(); | 209 obj)->shared()->name())->ToCString(); |
| 217 CHECK_EQ(func_name, *found_name); | 210 CHECK_EQ(func_name, *found_name); |
| 218 } | 211 } |
| 219 | 212 |
| 220 | 213 |
| 221 static void SetGlobalProperty(const char* name, Local<Value> value) { | |
| 222 env->Global()->Set(String::New(name), value); | |
| 223 } | |
| 224 | |
| 225 | |
| 226 static Handle<v8::internal::String> NewString(const char* s) { | |
| 227 return i::Factory::NewStringFromAscii(i::CStrVector(s)); | |
| 228 } | |
| 229 | |
| 230 | |
| 231 // This C++ function is called as a constructor, to grab the frame pointer | 214 // This C++ function is called as a constructor, to grab the frame pointer |
| 232 // from the calling function. When this function runs, the stack contains | 215 // from the calling function. When this function runs, the stack contains |
| 233 // a C_Entry frame and a Construct frame above the calling function's frame. | 216 // a C_Entry frame and a Construct frame above the calling function's frame. |
| 234 static v8::Handle<Value> construct_call(const v8::Arguments& args) { | 217 static v8::Handle<Value> construct_call(const v8::Arguments& args) { |
| 235 i::StackFrameIterator frame_iterator; | 218 i::StackFrameIterator frame_iterator; |
| 236 CHECK(frame_iterator.frame()->is_exit()); | 219 CHECK(frame_iterator.frame()->is_exit()); |
| 237 frame_iterator.Advance(); | 220 frame_iterator.Advance(); |
| 238 CHECK(frame_iterator.frame()->is_construct()); | 221 CHECK(frame_iterator.frame()->is_construct()); |
| 239 frame_iterator.Advance(); | 222 frame_iterator.Advance(); |
| 240 i::StackFrame* calling_frame = frame_iterator.frame(); | 223 i::StackFrame* calling_frame = frame_iterator.frame(); |
| (...skipping 25 matching lines...) Expand all Loading... |
| 266 } | 249 } |
| 267 | 250 |
| 268 | 251 |
| 269 // Creates a global function named 'func_name' that calls the tracing | 252 // Creates a global function named 'func_name' that calls the tracing |
| 270 // function 'trace_func_name' with an actual EBP register value, | 253 // function 'trace_func_name' with an actual EBP register value, |
| 271 // encoded as one or two Smis. | 254 // encoded as one or two Smis. |
| 272 static void CreateTraceCallerFunction(const char* func_name, | 255 static void CreateTraceCallerFunction(const char* func_name, |
| 273 const char* trace_func_name) { | 256 const char* trace_func_name) { |
| 274 i::EmbeddedVector<char, 256> trace_call_buf; | 257 i::EmbeddedVector<char, 256> trace_call_buf; |
| 275 i::OS::SNPrintF(trace_call_buf, | 258 i::OS::SNPrintF(trace_call_buf, |
| 276 "fp = new FPGrabber(); %s(fp.low_bits, fp.high_bits);", | 259 "function %s() {" |
| 277 trace_func_name); | 260 " fp = new FPGrabber();" |
| 261 " %s(fp.low_bits, fp.high_bits);" |
| 262 "}", |
| 263 func_name, trace_func_name); |
| 278 | 264 |
| 279 // Create the FPGrabber function, which grabs the caller's frame pointer | 265 // Create the FPGrabber function, which grabs the caller's frame pointer |
| 280 // when called as a constructor. | 266 // when called as a constructor. |
| 281 CreateFramePointerGrabberConstructor("FPGrabber"); | 267 CreateFramePointerGrabberConstructor("FPGrabber"); |
| 282 | 268 |
| 283 // Compile the script. | 269 // Compile the script. |
| 284 Handle<JSFunction> func = CompileFunction(trace_call_buf.start()); | 270 CompileRun(trace_call_buf.start()); |
| 285 CHECK(!func.is_null()); | |
| 286 func->shared()->set_name(*NewString(func_name)); | |
| 287 | |
| 288 #ifdef DEBUG | |
| 289 v8::internal::Code* func_code = func->code(); | |
| 290 CHECK(func_code->IsCode()); | |
| 291 func_code->Print(); | |
| 292 #endif | |
| 293 | |
| 294 SetGlobalProperty(func_name, v8::ToApi<Value>(func)); | |
| 295 } | 271 } |
| 296 | 272 |
| 297 | 273 |
| 298 // This test verifies that stack tracing works when called during | 274 // This test verifies that stack tracing works when called during |
| 299 // execution of a native function called from JS code. In this case, | 275 // execution of a native function called from JS code. In this case, |
| 300 // StackTracer uses Top::c_entry_fp as a starting point for stack | 276 // StackTracer uses Top::c_entry_fp as a starting point for stack |
| 301 // walking. | 277 // walking. |
| 302 TEST(CFromJSStackTrace) { | 278 TEST(CFromJSStackTrace) { |
| 303 TickSample sample; | 279 TickSample sample; |
| 304 InitTraceEnv(&sample); | 280 InitTraceEnv(&sample); |
| (...skipping 109 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 414 CHECK_EQ(0, GetJsEntrySp()); | 390 CHECK_EQ(0, GetJsEntrySp()); |
| 415 CompileRun("a = 1; b = a + 1;"); | 391 CompileRun("a = 1; b = a + 1;"); |
| 416 CHECK_EQ(0, GetJsEntrySp()); | 392 CHECK_EQ(0, GetJsEntrySp()); |
| 417 CompileRun("js_entry_sp();"); | 393 CompileRun("js_entry_sp();"); |
| 418 CHECK_EQ(0, GetJsEntrySp()); | 394 CHECK_EQ(0, GetJsEntrySp()); |
| 419 CompileRun("js_entry_sp_level2();"); | 395 CompileRun("js_entry_sp_level2();"); |
| 420 CHECK_EQ(0, GetJsEntrySp()); | 396 CHECK_EQ(0, GetJsEntrySp()); |
| 421 } | 397 } |
| 422 | 398 |
| 423 #endif // ENABLE_LOGGING_AND_PROFILING | 399 #endif // ENABLE_LOGGING_AND_PROFILING |
| OLD | NEW |