OLD | NEW |
1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 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 25 matching lines...) Expand all Loading... |
36 #include "safepoint-table.h" | 36 #include "safepoint-table.h" |
37 #include "scopeinfo.h" | 37 #include "scopeinfo.h" |
38 #include "string-stream.h" | 38 #include "string-stream.h" |
39 | 39 |
40 #include "allocation-inl.h" | 40 #include "allocation-inl.h" |
41 | 41 |
42 namespace v8 { | 42 namespace v8 { |
43 namespace internal { | 43 namespace internal { |
44 | 44 |
45 | 45 |
46 static ReturnAddressLocationResolver return_address_location_resolver = NULL; | 46 ReturnAddressLocationResolver |
47 | 47 StackFrame::return_address_location_resolver_ = NULL; |
48 | |
49 // Resolves pc_address through the resolution address function if one is set. | |
50 static inline Address* ResolveReturnAddressLocation(Address* pc_address) { | |
51 if (return_address_location_resolver == NULL) { | |
52 return pc_address; | |
53 } else { | |
54 return reinterpret_cast<Address*>( | |
55 return_address_location_resolver( | |
56 reinterpret_cast<uintptr_t>(pc_address))); | |
57 } | |
58 } | |
59 | 48 |
60 | 49 |
61 // Iterator that supports traversing the stack handlers of a | 50 // Iterator that supports traversing the stack handlers of a |
62 // particular frame. Needs to know the top of the handler chain. | 51 // particular frame. Needs to know the top of the handler chain. |
63 class StackHandlerIterator BASE_EMBEDDED { | 52 class StackHandlerIterator BASE_EMBEDDED { |
64 public: | 53 public: |
65 StackHandlerIterator(const StackFrame* frame, StackHandler* handler) | 54 StackHandlerIterator(const StackFrame* frame, StackHandler* handler) |
66 : limit_(frame->fp()), handler_(handler) { | 55 : limit_(frame->fp()), handler_(handler) { |
67 // Make sure the handler has already been unwound to this frame. | 56 // Make sure the handler has already been unwound to this frame. |
68 ASSERT(frame->sp() <= handler->address()); | 57 ASSERT(frame->sp() <= handler->address()); |
(...skipping 137 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
206 | 195 |
207 | 196 |
208 void StackTraceFrameIterator::Advance() { | 197 void StackTraceFrameIterator::Advance() { |
209 while (true) { | 198 while (true) { |
210 JavaScriptFrameIterator::Advance(); | 199 JavaScriptFrameIterator::Advance(); |
211 if (done()) return; | 200 if (done()) return; |
212 if (IsValidFrame()) return; | 201 if (IsValidFrame()) return; |
213 } | 202 } |
214 } | 203 } |
215 | 204 |
| 205 |
216 bool StackTraceFrameIterator::IsValidFrame() { | 206 bool StackTraceFrameIterator::IsValidFrame() { |
217 if (!frame()->function()->IsJSFunction()) return false; | 207 if (!frame()->function()->IsJSFunction()) return false; |
218 Object* script = JSFunction::cast(frame()->function())->shared()->script(); | 208 Object* script = JSFunction::cast(frame()->function())->shared()->script(); |
219 // Don't show functions from native scripts to user. | 209 // Don't show functions from native scripts to user. |
220 return (script->IsScript() && | 210 return (script->IsScript() && |
221 Script::TYPE_NATIVE != Script::cast(script)->type()->value()); | 211 Script::TYPE_NATIVE != Script::cast(script)->type()->value()); |
222 } | 212 } |
223 | 213 |
224 | 214 |
225 // ------------------------------------------------------------------------- | 215 // ------------------------------------------------------------------------- |
226 | 216 |
227 | 217 |
228 SafeStackFrameIterator::SafeStackFrameIterator( | 218 SafeStackFrameIterator::SafeStackFrameIterator( |
229 Isolate* isolate, | 219 Isolate* isolate, |
230 Address fp, Address sp, Address low_bound, Address high_bound) : | 220 Address fp, Address sp, Address js_entry_sp) |
231 StackFrameIteratorBase(isolate, false), | 221 : StackFrameIteratorBase(isolate, false), |
232 low_bound_(low_bound), high_bound_(high_bound) { | 222 low_bound_(sp), |
| 223 high_bound_(js_entry_sp), |
| 224 top_frame_type_(StackFrame::NONE) { |
233 StackFrame::State state; | 225 StackFrame::State state; |
234 StackFrame::Type type; | 226 StackFrame::Type type; |
235 ThreadLocalTop* top = isolate->thread_local_top(); | 227 ThreadLocalTop* top = isolate->thread_local_top(); |
236 if (IsValidTop(top)) { | 228 if (IsValidTop(top)) { |
237 type = ExitFrame::GetStateForFramePointer(Isolate::c_entry_fp(top), &state); | 229 type = ExitFrame::GetStateForFramePointer(Isolate::c_entry_fp(top), &state); |
| 230 top_frame_type_ = type; |
238 } else if (IsValidStackAddress(fp)) { | 231 } else if (IsValidStackAddress(fp)) { |
239 ASSERT(fp != NULL); | 232 ASSERT(fp != NULL); |
240 state.fp = fp; | 233 state.fp = fp; |
241 state.sp = sp; | 234 state.sp = sp; |
242 state.pc_address = ResolveReturnAddressLocation( | 235 state.pc_address = StackFrame::ResolveReturnAddressLocation( |
243 reinterpret_cast<Address*>(StandardFrame::ComputePCAddress(fp))); | 236 reinterpret_cast<Address*>(StandardFrame::ComputePCAddress(fp))); |
244 type = StackFrame::ComputeType(this, &state); | 237 // StackFrame::ComputeType will read both kContextOffset and kMarkerOffset, |
| 238 // we check only that kMarkerOffset is within the stack bounds and do |
| 239 // compile time check that kContextOffset slot is pushed on the stack before |
| 240 // kMarkerOffset. |
| 241 STATIC_ASSERT(StandardFrameConstants::kMarkerOffset < |
| 242 StandardFrameConstants::kContextOffset); |
| 243 Address frame_marker = fp + StandardFrameConstants::kMarkerOffset; |
| 244 if (IsValidStackAddress(frame_marker)) { |
| 245 type = StackFrame::ComputeType(this, &state); |
| 246 top_frame_type_ = type; |
| 247 } else { |
| 248 // Mark the frame as JAVA_SCRIPT if we cannot determine its type. |
| 249 // The frame anyways will be skipped. |
| 250 type = StackFrame::JAVA_SCRIPT; |
| 251 // Top frame is incomplete so we cannot reliably determine its type. |
| 252 top_frame_type_ = StackFrame::NONE; |
| 253 } |
245 } else { | 254 } else { |
246 return; | 255 return; |
247 } | 256 } |
248 if (SingletonFor(type) == NULL) return; | 257 if (SingletonFor(type) == NULL) return; |
249 frame_ = SingletonFor(type, &state); | 258 frame_ = SingletonFor(type, &state); |
250 | 259 |
251 if (!done()) Advance(); | 260 if (!done()) Advance(); |
252 } | 261 } |
253 | 262 |
254 | 263 |
(...skipping 127 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
382 if (code != holder) { | 391 if (code != holder) { |
383 holder = reinterpret_cast<Code*>(code); | 392 holder = reinterpret_cast<Code*>(code); |
384 pc = holder->instruction_start() + pc_offset; | 393 pc = holder->instruction_start() + pc_offset; |
385 *pc_address = pc; | 394 *pc_address = pc; |
386 } | 395 } |
387 } | 396 } |
388 | 397 |
389 | 398 |
390 void StackFrame::SetReturnAddressLocationResolver( | 399 void StackFrame::SetReturnAddressLocationResolver( |
391 ReturnAddressLocationResolver resolver) { | 400 ReturnAddressLocationResolver resolver) { |
392 ASSERT(return_address_location_resolver == NULL); | 401 ASSERT(return_address_location_resolver_ == NULL); |
393 return_address_location_resolver = resolver; | 402 return_address_location_resolver_ = resolver; |
394 } | 403 } |
395 | 404 |
396 | 405 |
397 StackFrame::Type StackFrame::ComputeType(const StackFrameIteratorBase* iterator, | 406 StackFrame::Type StackFrame::ComputeType(const StackFrameIteratorBase* iterator, |
398 State* state) { | 407 State* state) { |
399 ASSERT(state->fp != NULL); | 408 ASSERT(state->fp != NULL); |
400 if (StandardFrame::IsArgumentsAdaptorFrame(state->fp)) { | 409 if (StandardFrame::IsArgumentsAdaptorFrame(state->fp)) { |
401 return ARGUMENTS_ADAPTOR; | 410 return ARGUMENTS_ADAPTOR; |
402 } | 411 } |
403 // The marker and function offsets overlap. If the marker isn't a | 412 // The marker and function offsets overlap. If the marker isn't a |
(...skipping 23 matching lines...) Expand all Loading... |
427 #endif | 436 #endif |
428 | 437 |
429 | 438 |
430 StackFrame::Type StackFrame::GetCallerState(State* state) const { | 439 StackFrame::Type StackFrame::GetCallerState(State* state) const { |
431 ComputeCallerState(state); | 440 ComputeCallerState(state); |
432 return ComputeType(iterator_, state); | 441 return ComputeType(iterator_, state); |
433 } | 442 } |
434 | 443 |
435 | 444 |
436 Address StackFrame::UnpaddedFP() const { | 445 Address StackFrame::UnpaddedFP() const { |
437 #if defined(V8_TARGET_ARCH_IA32) | 446 #if V8_TARGET_ARCH_IA32 |
438 if (!is_optimized()) return fp(); | 447 if (!is_optimized()) return fp(); |
439 int32_t alignment_state = Memory::int32_at( | 448 int32_t alignment_state = Memory::int32_at( |
440 fp() + JavaScriptFrameConstants::kDynamicAlignmentStateOffset); | 449 fp() + JavaScriptFrameConstants::kDynamicAlignmentStateOffset); |
441 | 450 |
442 return (alignment_state == kAlignmentPaddingPushed) ? | 451 return (alignment_state == kAlignmentPaddingPushed) ? |
443 (fp() + kPointerSize) : fp(); | 452 (fp() + kPointerSize) : fp(); |
444 #else | 453 #else |
445 return fp(); | 454 return fp(); |
446 #endif | 455 #endif |
447 } | 456 } |
(...skipping 1105 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1553 | 1562 |
1554 void SetUpJSCallerSavedCodeData() { | 1563 void SetUpJSCallerSavedCodeData() { |
1555 int i = 0; | 1564 int i = 0; |
1556 for (int r = 0; r < kNumRegs; r++) | 1565 for (int r = 0; r < kNumRegs; r++) |
1557 if ((kJSCallerSaved & (1 << r)) != 0) | 1566 if ((kJSCallerSaved & (1 << r)) != 0) |
1558 caller_saved_code_data.reg_code[i++] = r; | 1567 caller_saved_code_data.reg_code[i++] = r; |
1559 | 1568 |
1560 ASSERT(i == kNumJSCallerSaved); | 1569 ASSERT(i == kNumJSCallerSaved); |
1561 } | 1570 } |
1562 | 1571 |
| 1572 |
1563 int JSCallerSavedCode(int n) { | 1573 int JSCallerSavedCode(int n) { |
1564 ASSERT(0 <= n && n < kNumJSCallerSaved); | 1574 ASSERT(0 <= n && n < kNumJSCallerSaved); |
1565 return caller_saved_code_data.reg_code[n]; | 1575 return caller_saved_code_data.reg_code[n]; |
1566 } | 1576 } |
1567 | 1577 |
1568 | 1578 |
1569 #define DEFINE_WRAPPER(type, field) \ | 1579 #define DEFINE_WRAPPER(type, field) \ |
1570 class field##_Wrapper : public ZoneObject { \ | 1580 class field##_Wrapper : public ZoneObject { \ |
1571 public: /* NOLINT */ \ | 1581 public: /* NOLINT */ \ |
1572 field##_Wrapper(const field& original) : frame_(original) { \ | 1582 field##_Wrapper(const field& original) : frame_(original) { \ |
(...skipping 12 matching lines...) Expand all Loading... |
1585 } | 1595 } |
1586 | 1596 |
1587 switch (frame->type()) { | 1597 switch (frame->type()) { |
1588 STACK_FRAME_TYPE_LIST(FRAME_TYPE_CASE) | 1598 STACK_FRAME_TYPE_LIST(FRAME_TYPE_CASE) |
1589 default: UNREACHABLE(); | 1599 default: UNREACHABLE(); |
1590 } | 1600 } |
1591 #undef FRAME_TYPE_CASE | 1601 #undef FRAME_TYPE_CASE |
1592 return NULL; | 1602 return NULL; |
1593 } | 1603 } |
1594 | 1604 |
| 1605 |
1595 Vector<StackFrame*> CreateStackMap(Isolate* isolate, Zone* zone) { | 1606 Vector<StackFrame*> CreateStackMap(Isolate* isolate, Zone* zone) { |
1596 ZoneList<StackFrame*> list(10, zone); | 1607 ZoneList<StackFrame*> list(10, zone); |
1597 for (StackFrameIterator it(isolate); !it.done(); it.Advance()) { | 1608 for (StackFrameIterator it(isolate); !it.done(); it.Advance()) { |
1598 StackFrame* frame = AllocateFrameCopy(it.frame(), zone); | 1609 StackFrame* frame = AllocateFrameCopy(it.frame(), zone); |
1599 list.Add(frame, zone); | 1610 list.Add(frame, zone); |
1600 } | 1611 } |
1601 return list.ToVector(); | 1612 return list.ToVector(); |
1602 } | 1613 } |
1603 | 1614 |
1604 | 1615 |
1605 } } // namespace v8::internal | 1616 } } // namespace v8::internal |
OLD | NEW |