| OLD | NEW |
| 1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 the V8 project authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "src/frames.h" | 5 #include "src/frames.h" |
| 6 | 6 |
| 7 #include <memory> | 7 #include <memory> |
| 8 #include <sstream> | 8 #include <sstream> |
| 9 | 9 |
| 10 #include "src/base/bits.h" | 10 #include "src/base/bits.h" |
| (...skipping 164 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 175 } | 175 } |
| 176 | 176 |
| 177 void StackTraceFrameIterator::AdvanceToArgumentsFrame() { | 177 void StackTraceFrameIterator::AdvanceToArgumentsFrame() { |
| 178 if (!is_javascript() || !javascript_frame()->has_adapted_arguments()) return; | 178 if (!is_javascript() || !javascript_frame()->has_adapted_arguments()) return; |
| 179 iterator_.Advance(); | 179 iterator_.Advance(); |
| 180 DCHECK(iterator_.frame()->is_arguments_adaptor()); | 180 DCHECK(iterator_.frame()->is_arguments_adaptor()); |
| 181 } | 181 } |
| 182 | 182 |
| 183 // ------------------------------------------------------------------------- | 183 // ------------------------------------------------------------------------- |
| 184 | 184 |
| 185 namespace { |
| 186 |
| 187 bool IsInterpreterFramePc(Isolate* isolate, Address pc) { |
| 188 Code* interpreter_entry_trampoline = |
| 189 isolate->builtins()->builtin(Builtins::kInterpreterEntryTrampoline); |
| 190 Code* interpreter_bytecode_advance = |
| 191 isolate->builtins()->builtin(Builtins::kInterpreterEnterBytecodeAdvance); |
| 192 Code* interpreter_bytecode_dispatch = |
| 193 isolate->builtins()->builtin(Builtins::kInterpreterEnterBytecodeDispatch); |
| 194 |
| 195 return (pc >= interpreter_entry_trampoline->instruction_start() && |
| 196 pc < interpreter_entry_trampoline->instruction_end()) || |
| 197 (pc >= interpreter_bytecode_advance->instruction_start() && |
| 198 pc < interpreter_bytecode_advance->instruction_end()) || |
| 199 (pc >= interpreter_bytecode_dispatch->instruction_start() && |
| 200 pc < interpreter_bytecode_dispatch->instruction_end()); |
| 201 } |
| 202 |
| 203 DISABLE_ASAN Address ReadMemoryAt(Address address) { |
| 204 return Memory::Address_at(address); |
| 205 } |
| 206 |
| 207 } // namespace |
| 185 | 208 |
| 186 SafeStackFrameIterator::SafeStackFrameIterator( | 209 SafeStackFrameIterator::SafeStackFrameIterator( |
| 187 Isolate* isolate, | 210 Isolate* isolate, |
| 188 Address fp, Address sp, Address js_entry_sp) | 211 Address fp, Address sp, Address js_entry_sp) |
| 189 : StackFrameIteratorBase(isolate, false), | 212 : StackFrameIteratorBase(isolate, false), |
| 190 low_bound_(sp), | 213 low_bound_(sp), |
| 191 high_bound_(js_entry_sp), | 214 high_bound_(js_entry_sp), |
| 192 top_frame_type_(StackFrame::NONE), | 215 top_frame_type_(StackFrame::NONE), |
| 193 external_callback_scope_(isolate->external_callback_scope()) { | 216 external_callback_scope_(isolate->external_callback_scope()) { |
| 194 StackFrame::State state; | 217 StackFrame::State state; |
| 195 StackFrame::Type type; | 218 StackFrame::Type type; |
| 196 ThreadLocalTop* top = isolate->thread_local_top(); | 219 ThreadLocalTop* top = isolate->thread_local_top(); |
| 220 bool advance_frame = true; |
| 197 if (IsValidTop(top)) { | 221 if (IsValidTop(top)) { |
| 198 type = ExitFrame::GetStateForFramePointer(Isolate::c_entry_fp(top), &state); | 222 type = ExitFrame::GetStateForFramePointer(Isolate::c_entry_fp(top), &state); |
| 199 top_frame_type_ = type; | 223 top_frame_type_ = type; |
| 200 } else if (IsValidStackAddress(fp)) { | 224 } else if (IsValidStackAddress(fp)) { |
| 201 DCHECK(fp != NULL); | 225 DCHECK(fp != NULL); |
| 202 state.fp = fp; | 226 state.fp = fp; |
| 203 state.sp = sp; | 227 state.sp = sp; |
| 204 state.pc_address = StackFrame::ResolveReturnAddressLocation( | 228 state.pc_address = StackFrame::ResolveReturnAddressLocation( |
| 205 reinterpret_cast<Address*>(StandardFrame::ComputePCAddress(fp))); | 229 reinterpret_cast<Address*>(StandardFrame::ComputePCAddress(fp))); |
| 230 |
| 231 // If the top of stack is a return address to the interpreter trampoline, |
| 232 // then we are likely in a bytecode handler with elided frame. In that |
| 233 // case, set the PC properly and make sure we do not drop the frame. |
| 234 if (IsValidStackAddress(sp)) { |
| 235 MSAN_MEMORY_IS_INITIALIZED(sp, kPointerSize); |
| 236 Address tos = ReadMemoryAt(reinterpret_cast<Address>(sp)); |
| 237 if (IsInterpreterFramePc(isolate, tos)) { |
| 238 state.pc_address = reinterpret_cast<Address*>(sp); |
| 239 advance_frame = false; |
| 240 } |
| 241 } |
| 242 |
| 206 // StackFrame::ComputeType will read both kContextOffset and kMarkerOffset, | 243 // StackFrame::ComputeType will read both kContextOffset and kMarkerOffset, |
| 207 // we check only that kMarkerOffset is within the stack bounds and do | 244 // we check only that kMarkerOffset is within the stack bounds and do |
| 208 // compile time check that kContextOffset slot is pushed on the stack before | 245 // compile time check that kContextOffset slot is pushed on the stack before |
| 209 // kMarkerOffset. | 246 // kMarkerOffset. |
| 210 STATIC_ASSERT(StandardFrameConstants::kFunctionOffset < | 247 STATIC_ASSERT(StandardFrameConstants::kFunctionOffset < |
| 211 StandardFrameConstants::kContextOffset); | 248 StandardFrameConstants::kContextOffset); |
| 212 Address frame_marker = fp + StandardFrameConstants::kFunctionOffset; | 249 Address frame_marker = fp + StandardFrameConstants::kFunctionOffset; |
| 213 if (IsValidStackAddress(frame_marker)) { | 250 if (IsValidStackAddress(frame_marker)) { |
| 214 type = StackFrame::ComputeType(this, &state); | 251 type = StackFrame::ComputeType(this, &state); |
| 215 top_frame_type_ = type; | 252 top_frame_type_ = type; |
| 253 // We only keep the top frame if we believe it to be interpreted frame. |
| 254 if (type != StackFrame::INTERPRETED) { |
| 255 advance_frame = true; |
| 256 } |
| 216 } else { | 257 } else { |
| 217 // Mark the frame as JAVA_SCRIPT if we cannot determine its type. | 258 // Mark the frame as JAVA_SCRIPT if we cannot determine its type. |
| 218 // The frame anyways will be skipped. | 259 // The frame anyways will be skipped. |
| 219 type = StackFrame::JAVA_SCRIPT; | 260 type = StackFrame::JAVA_SCRIPT; |
| 220 // Top frame is incomplete so we cannot reliably determine its type. | 261 // Top frame is incomplete so we cannot reliably determine its type. |
| 221 top_frame_type_ = StackFrame::NONE; | 262 top_frame_type_ = StackFrame::NONE; |
| 222 } | 263 } |
| 223 } else { | 264 } else { |
| 224 return; | 265 return; |
| 225 } | 266 } |
| 226 frame_ = SingletonFor(type, &state); | 267 frame_ = SingletonFor(type, &state); |
| 227 if (frame_) Advance(); | 268 if (advance_frame && frame_) Advance(); |
| 228 } | 269 } |
| 229 | 270 |
| 230 | 271 |
| 231 bool SafeStackFrameIterator::IsValidTop(ThreadLocalTop* top) const { | 272 bool SafeStackFrameIterator::IsValidTop(ThreadLocalTop* top) const { |
| 232 Address c_entry_fp = Isolate::c_entry_fp(top); | 273 Address c_entry_fp = Isolate::c_entry_fp(top); |
| 233 if (!IsValidExitFrame(c_entry_fp)) return false; | 274 if (!IsValidExitFrame(c_entry_fp)) return false; |
| 234 // There should be at least one JS_ENTRY stack handler. | 275 // There should be at least one JS_ENTRY stack handler. |
| 235 Address handler = Isolate::handler(top); | 276 Address handler = Isolate::handler(top); |
| 236 if (handler == NULL) return false; | 277 if (handler == NULL) return false; |
| 237 // Check that there are no js frames on top of the native frames. | 278 // Check that there are no js frames on top of the native frames. |
| (...skipping 144 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 382 } | 423 } |
| 383 } | 424 } |
| 384 | 425 |
| 385 | 426 |
| 386 void StackFrame::SetReturnAddressLocationResolver( | 427 void StackFrame::SetReturnAddressLocationResolver( |
| 387 ReturnAddressLocationResolver resolver) { | 428 ReturnAddressLocationResolver resolver) { |
| 388 DCHECK(return_address_location_resolver_ == NULL); | 429 DCHECK(return_address_location_resolver_ == NULL); |
| 389 return_address_location_resolver_ = resolver; | 430 return_address_location_resolver_ = resolver; |
| 390 } | 431 } |
| 391 | 432 |
| 392 static bool IsInterpreterFramePc(Isolate* isolate, Address pc) { | |
| 393 Code* interpreter_entry_trampoline = | |
| 394 isolate->builtins()->builtin(Builtins::kInterpreterEntryTrampoline); | |
| 395 Code* interpreter_bytecode_advance = | |
| 396 isolate->builtins()->builtin(Builtins::kInterpreterEnterBytecodeAdvance); | |
| 397 Code* interpreter_bytecode_dispatch = | |
| 398 isolate->builtins()->builtin(Builtins::kInterpreterEnterBytecodeDispatch); | |
| 399 | |
| 400 return (pc >= interpreter_entry_trampoline->instruction_start() && | |
| 401 pc < interpreter_entry_trampoline->instruction_end()) || | |
| 402 (pc >= interpreter_bytecode_advance->instruction_start() && | |
| 403 pc < interpreter_bytecode_advance->instruction_end()) || | |
| 404 (pc >= interpreter_bytecode_dispatch->instruction_start() && | |
| 405 pc < interpreter_bytecode_dispatch->instruction_end()); | |
| 406 } | |
| 407 | |
| 408 StackFrame::Type StackFrame::ComputeType(const StackFrameIteratorBase* iterator, | 433 StackFrame::Type StackFrame::ComputeType(const StackFrameIteratorBase* iterator, |
| 409 State* state) { | 434 State* state) { |
| 410 DCHECK(state->fp != NULL); | 435 DCHECK(state->fp != NULL); |
| 411 | 436 |
| 412 MSAN_MEMORY_IS_INITIALIZED( | 437 MSAN_MEMORY_IS_INITIALIZED( |
| 413 state->fp + CommonFrameConstants::kContextOrFrameTypeOffset, | 438 state->fp + CommonFrameConstants::kContextOrFrameTypeOffset, |
| 414 kPointerSize); | 439 kPointerSize); |
| 415 Object* marker = Memory::Object_at( | 440 Object* marker = Memory::Object_at( |
| 416 state->fp + CommonFrameConstants::kContextOrFrameTypeOffset); | 441 state->fp + CommonFrameConstants::kContextOrFrameTypeOffset); |
| 417 if (!iterator->can_access_heap_objects_) { | 442 if (!iterator->can_access_heap_objects_) { |
| (...skipping 1819 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2237 for (StackFrameIterator it(isolate); !it.done(); it.Advance()) { | 2262 for (StackFrameIterator it(isolate); !it.done(); it.Advance()) { |
| 2238 StackFrame* frame = AllocateFrameCopy(it.frame(), zone); | 2263 StackFrame* frame = AllocateFrameCopy(it.frame(), zone); |
| 2239 list.Add(frame, zone); | 2264 list.Add(frame, zone); |
| 2240 } | 2265 } |
| 2241 return list.ToVector(); | 2266 return list.ToVector(); |
| 2242 } | 2267 } |
| 2243 | 2268 |
| 2244 | 2269 |
| 2245 } // namespace internal | 2270 } // namespace internal |
| 2246 } // namespace v8 | 2271 } // namespace v8 |
| OLD | NEW |