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

Side by Side Diff: src/debug.cc

Issue 87025: Handle breaks on keyed IC loads which can have an inlined version (Closed) Base URL: http://v8.googlecode.com/svn/branches/bleeding_edge/
Patch Set: '' Created 11 years, 8 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 | « src/debug.h ('k') | src/ic.h » ('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 2006-2008 the V8 project authors. All rights reserved. 1 // Copyright 2006-2008 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 17 matching lines...) Expand all
28 #include "v8.h" 28 #include "v8.h"
29 29
30 #include "api.h" 30 #include "api.h"
31 #include "arguments.h" 31 #include "arguments.h"
32 #include "bootstrapper.h" 32 #include "bootstrapper.h"
33 #include "code-stubs.h" 33 #include "code-stubs.h"
34 #include "compiler.h" 34 #include "compiler.h"
35 #include "debug.h" 35 #include "debug.h"
36 #include "execution.h" 36 #include "execution.h"
37 #include "global-handles.h" 37 #include "global-handles.h"
38 #include "ic.h"
39 #include "ic-inl.h"
38 #include "natives.h" 40 #include "natives.h"
39 #include "stub-cache.h" 41 #include "stub-cache.h"
40 #include "log.h" 42 #include "log.h"
41 43
42 namespace v8 { namespace internal { 44 namespace v8 { namespace internal {
43 45
44 #ifdef ENABLE_DEBUGGER_SUPPORT 46 #ifdef ENABLE_DEBUGGER_SUPPORT
45 static void PrintLn(v8::Local<v8::Value> value) { 47 static void PrintLn(v8::Local<v8::Value> value) {
46 v8::Local<v8::String> s = value->ToString(); 48 v8::Local<v8::String> s = value->ToString();
47 char* data = NewArray<char>(s->Length() + 1); 49 char* data = NewArray<char>(s->Length() + 1);
(...skipping 234 matching lines...) Expand 10 before | Expand all | Expand 10 after
282 // function twice might happen when stepping in a function with an exception 284 // function twice might happen when stepping in a function with an exception
283 // handler as the handler and the function is the same. 285 // handler as the handler and the function is the same.
284 if (IsDebugBreak()) { 286 if (IsDebugBreak()) {
285 return; 287 return;
286 } 288 }
287 289
288 if (RelocInfo::IsJSReturn(rmode())) { 290 if (RelocInfo::IsJSReturn(rmode())) {
289 // Patch the frame exit code with a break point. 291 // Patch the frame exit code with a break point.
290 SetDebugBreakAtReturn(); 292 SetDebugBreakAtReturn();
291 } else { 293 } else {
292 // Patch the original code with the current address as the current address 294 // Patch the IC call.
293 // might have changed by the inline caching since the code was copied. 295 SetDebugBreakAtIC();
294 original_rinfo()->set_target_address(rinfo()->target_address());
295
296 // Patch the code to invoke the builtin debug break function matching the
297 // calling convention used by the call site.
298 Handle<Code> dbgbrk_code(Debug::FindDebugBreak(rinfo()));
299 rinfo()->set_target_address(dbgbrk_code->entry());
300 } 296 }
301 ASSERT(IsDebugBreak()); 297 ASSERT(IsDebugBreak());
302 } 298 }
303 299
304 300
305 void BreakLocationIterator::ClearDebugBreak() { 301 void BreakLocationIterator::ClearDebugBreak() {
306 if (RelocInfo::IsJSReturn(rmode())) { 302 if (RelocInfo::IsJSReturn(rmode())) {
307 // Restore the frame exit code. 303 // Restore the frame exit code.
308 ClearDebugBreakAtReturn(); 304 ClearDebugBreakAtReturn();
309 } else { 305 } else {
310 // Patch the code to the original invoke. 306 // Patch the IC call.
311 rinfo()->set_target_address(original_rinfo()->target_address()); 307 ClearDebugBreakAtIC();
312 } 308 }
313 ASSERT(!IsDebugBreak()); 309 ASSERT(!IsDebugBreak());
314 } 310 }
315 311
316 312
317 void BreakLocationIterator::PrepareStepIn() { 313 void BreakLocationIterator::PrepareStepIn() {
318 HandleScope scope; 314 HandleScope scope;
319 315
320 // Step in can only be prepared if currently positioned on an IC call or 316 // Step in can only be prepared if currently positioned on an IC call or
321 // construct call. 317 // construct call.
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after
354 // Check whether there is a debug break at the current position. 350 // Check whether there is a debug break at the current position.
355 bool BreakLocationIterator::IsDebugBreak() { 351 bool BreakLocationIterator::IsDebugBreak() {
356 if (RelocInfo::IsJSReturn(rmode())) { 352 if (RelocInfo::IsJSReturn(rmode())) {
357 return IsDebugBreakAtReturn(); 353 return IsDebugBreakAtReturn();
358 } else { 354 } else {
359 return Debug::IsDebugBreak(rinfo()->target_address()); 355 return Debug::IsDebugBreak(rinfo()->target_address());
360 } 356 }
361 } 357 }
362 358
363 359
360 void BreakLocationIterator::SetDebugBreakAtIC() {
361 // Patch the original code with the current address as the current address
362 // might have changed by the inline caching since the code was copied.
363 original_rinfo()->set_target_address(rinfo()->target_address());
364
365 RelocInfo::Mode mode = rmode();
366 if (RelocInfo::IsCodeTarget(mode)) {
367 Address target = rinfo()->target_address();
368 Handle<Code> code(Code::GetCodeFromTargetAddress(target));
369
370 // Patch the code to invoke the builtin debug break function matching the
371 // calling convention used by the call site.
372 Handle<Code> dbgbrk_code(Debug::FindDebugBreak(code, mode));
373 rinfo()->set_target_address(dbgbrk_code->entry());
374
375 // For stubs that refer back to an inlined version clear the cached map for
376 // the inlined case to always go through the IC. As long as the break point
377 // is set the patching performed by the runtime system will take place in
378 // the code copy and will therefore have no effect on the running code
379 // keeping it from using the inlined code.
380 if (code->is_keyed_load_stub() && KeyedLoadIC::HasInlinedVersion(pc())) {
381 KeyedLoadIC::ClearInlinedVersion(pc());
382 }
383 }
384 }
385
386
387 void BreakLocationIterator::ClearDebugBreakAtIC() {
388 // Patch the code to the original invoke.
389 rinfo()->set_target_address(original_rinfo()->target_address());
390 }
391
392
364 Object* BreakLocationIterator::BreakPointObjects() { 393 Object* BreakLocationIterator::BreakPointObjects() {
365 return debug_info_->GetBreakPointObjects(code_position()); 394 return debug_info_->GetBreakPointObjects(code_position());
366 } 395 }
367 396
368 397
369 // Clear out all the debug break code. This is ONLY supposed to be used when 398 // Clear out all the debug break code. This is ONLY supposed to be used when
370 // shutting down the debugger as it will leave the break point information in 399 // shutting down the debugger as it will leave the break point information in
371 // DebugInfo even though the code is patched back to the non break point state. 400 // DebugInfo even though the code is patched back to the non break point state.
372 void BreakLocationIterator::ClearAllDebugBreak() { 401 void BreakLocationIterator::ClearAllDebugBreak() {
373 while (!Done()) { 402 while (!Done()) {
(...skipping 675 matching lines...) Expand 10 before | Expand all | Expand 10 after
1049 // Check whether a code stub with the specified major key is a possible break 1078 // Check whether a code stub with the specified major key is a possible break
1050 // location. 1079 // location.
1051 bool Debug::IsBreakStub(Code* code) { 1080 bool Debug::IsBreakStub(Code* code) {
1052 CodeStub::Major major_key = code->major_key(); 1081 CodeStub::Major major_key = code->major_key();
1053 return major_key == CodeStub::CallFunction || 1082 return major_key == CodeStub::CallFunction ||
1054 major_key == CodeStub::StackCheck; 1083 major_key == CodeStub::StackCheck;
1055 } 1084 }
1056 1085
1057 1086
1058 // Find the builtin to use for invoking the debug break 1087 // Find the builtin to use for invoking the debug break
1059 Handle<Code> Debug::FindDebugBreak(RelocInfo* rinfo) { 1088 Handle<Code> Debug::FindDebugBreak(Handle<Code> code, RelocInfo::Mode mode) {
1060 // Find the builtin debug break function matching the calling convention 1089 // Find the builtin debug break function matching the calling convention
1061 // used by the call site. 1090 // used by the call site.
1062 RelocInfo::Mode mode = rinfo->rmode(); 1091 if (code->is_inline_cache_stub()) {
1063 1092 if (code->is_call_stub()) {
1064 if (RelocInfo::IsCodeTarget(mode)) { 1093 return ComputeCallDebugBreak(code->arguments_count());
1065 Address target = rinfo->target_address();
1066 Code* code = Code::GetCodeFromTargetAddress(target);
1067 if (code->is_inline_cache_stub()) {
1068 if (code->is_call_stub()) {
1069 return ComputeCallDebugBreak(code->arguments_count());
1070 }
1071 if (code->is_load_stub()) {
1072 return Handle<Code>(Builtins::builtin(Builtins::LoadIC_DebugBreak));
1073 }
1074 if (code->is_store_stub()) {
1075 return Handle<Code>(Builtins::builtin(Builtins::StoreIC_DebugBreak));
1076 }
1077 if (code->is_keyed_load_stub()) {
1078 Handle<Code> result =
1079 Handle<Code>(Builtins::builtin(Builtins::KeyedLoadIC_DebugBreak));
1080 return result;
1081 }
1082 if (code->is_keyed_store_stub()) {
1083 Handle<Code> result =
1084 Handle<Code>(Builtins::builtin(Builtins::KeyedStoreIC_DebugBreak));
1085 return result;
1086 }
1087 } 1094 }
1088 if (RelocInfo::IsConstructCall(mode)) { 1095 if (code->is_load_stub()) {
1096 return Handle<Code>(Builtins::builtin(Builtins::LoadIC_DebugBreak));
1097 }
1098 if (code->is_store_stub()) {
1099 return Handle<Code>(Builtins::builtin(Builtins::StoreIC_DebugBreak));
1100 }
1101 if (code->is_keyed_load_stub()) {
1089 Handle<Code> result = 1102 Handle<Code> result =
1090 Handle<Code>(Builtins::builtin(Builtins::ConstructCall_DebugBreak)); 1103 Handle<Code>(Builtins::builtin(Builtins::KeyedLoadIC_DebugBreak));
1091 return result; 1104 return result;
1092 } 1105 }
1093 if (code->kind() == Code::STUB) { 1106 if (code->is_keyed_store_stub()) {
1094 ASSERT(code->major_key() == CodeStub::CallFunction ||
1095 code->major_key() == CodeStub::StackCheck);
1096 Handle<Code> result = 1107 Handle<Code> result =
1097 Handle<Code>(Builtins::builtin(Builtins::StubNoRegisters_DebugBreak)); 1108 Handle<Code>(Builtins::builtin(Builtins::KeyedStoreIC_DebugBreak));
1098 return result; 1109 return result;
1099 } 1110 }
1100 } 1111 }
1112 if (RelocInfo::IsConstructCall(mode)) {
1113 Handle<Code> result =
1114 Handle<Code>(Builtins::builtin(Builtins::ConstructCall_DebugBreak));
1115 return result;
1116 }
1117 if (code->kind() == Code::STUB) {
1118 ASSERT(code->major_key() == CodeStub::CallFunction ||
1119 code->major_key() == CodeStub::StackCheck);
1120 Handle<Code> result =
1121 Handle<Code>(Builtins::builtin(Builtins::StubNoRegisters_DebugBreak));
1122 return result;
1123 }
1101 1124
1102 UNREACHABLE(); 1125 UNREACHABLE();
1103 return Handle<Code>::null(); 1126 return Handle<Code>::null();
1104 } 1127 }
1105 1128
1106 1129
1107 // Simple function for returning the source positions for active break points. 1130 // Simple function for returning the source positions for active break points.
1108 Handle<Object> Debug::GetSourceBreakLocations( 1131 Handle<Object> Debug::GetSourceBreakLocations(
1109 Handle<SharedFunctionInfo> shared) { 1132 Handle<SharedFunctionInfo> shared) {
1110 if (!HasDebugInfo(shared)) return Handle<Object>(Heap::undefined_value()); 1133 if (!HasDebugInfo(shared)) return Handle<Object>(Heap::undefined_value());
(...skipping 721 matching lines...) Expand 10 before | Expand all | Expand 10 after
1832 continue; 1855 continue;
1833 } 1856 }
1834 1857
1835 // Invoke JavaScript to process the debug request. 1858 // Invoke JavaScript to process the debug request.
1836 v8::Local<v8::String> fun_name; 1859 v8::Local<v8::String> fun_name;
1837 v8::Local<v8::Function> fun; 1860 v8::Local<v8::Function> fun;
1838 v8::Local<v8::Value> request; 1861 v8::Local<v8::Value> request;
1839 v8::TryCatch try_catch; 1862 v8::TryCatch try_catch;
1840 fun_name = v8::String::New("processDebugRequest"); 1863 fun_name = v8::String::New("processDebugRequest");
1841 fun = v8::Function::Cast(*cmd_processor->Get(fun_name)); 1864 fun = v8::Function::Cast(*cmd_processor->Get(fun_name));
1842 1865
1843 request = v8::String::New(command.text().start(), 1866 request = v8::String::New(command.text().start(),
1844 command.text().length()); 1867 command.text().length());
1845 command.text().Dispose(); 1868 command.text().Dispose();
1846 static const int kArgc = 1; 1869 static const int kArgc = 1;
1847 v8::Handle<Value> argv[kArgc] = { request }; 1870 v8::Handle<Value> argv[kArgc] = { request };
1848 v8::Local<v8::Value> response_val = fun->Call(cmd_processor, kArgc, argv); 1871 v8::Local<v8::Value> response_val = fun->Call(cmd_processor, kArgc, argv);
1849 1872
1850 // Get the response. 1873 // Get the response.
1851 v8::Local<v8::String> response; 1874 v8::Local<v8::String> response;
1852 bool running = false; 1875 bool running = false;
(...skipping 348 matching lines...) Expand 10 before | Expand all | Expand 10 after
2201 return Message(); 2224 return Message();
2202 } 2225 }
2203 2226
2204 2227
2205 MessageQueue::MessageQueue(int size) : start_(0), end_(0), size_(size) { 2228 MessageQueue::MessageQueue(int size) : start_(0), end_(0), size_(size) {
2206 messages_ = NewArray<Message>(size); 2229 messages_ = NewArray<Message>(size);
2207 } 2230 }
2208 2231
2209 2232
2210 MessageQueue::~MessageQueue() { 2233 MessageQueue::~MessageQueue() {
2211 while(!IsEmpty()) { 2234 while (!IsEmpty()) {
2212 Message m = Get(); 2235 Message m = Get();
2213 m.Dispose(); 2236 m.Dispose();
2214 } 2237 }
2215 DeleteArray(messages_); 2238 DeleteArray(messages_);
2216 } 2239 }
2217 2240
2218 2241
2219 Message MessageQueue::Get() { 2242 Message MessageQueue::Get() {
2220 ASSERT(!IsEmpty()); 2243 ASSERT(!IsEmpty());
2221 int result = start_; 2244 int result = start_;
(...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after
2279 2302
2280 2303
2281 void LockingMessageQueue::Clear() { 2304 void LockingMessageQueue::Clear() {
2282 ScopedLock sl(lock_); 2305 ScopedLock sl(lock_);
2283 queue_.Clear(); 2306 queue_.Clear();
2284 } 2307 }
2285 2308
2286 #endif // ENABLE_DEBUGGER_SUPPORT 2309 #endif // ENABLE_DEBUGGER_SUPPORT
2287 2310
2288 } } // namespace v8::internal 2311 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « src/debug.h ('k') | src/ic.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698