| 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 |