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 <sstream> | 7 #include <sstream> |
8 | 8 |
9 #include "src/v8.h" | 9 #include "src/v8.h" |
10 | 10 |
(...skipping 303 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
314 SingletonFor(frame->GetCallerState(&state)) != NULL; | 314 SingletonFor(frame->GetCallerState(&state)) != NULL; |
315 } | 315 } |
316 | 316 |
317 | 317 |
318 bool SafeStackFrameIterator::IsValidExitFrame(Address fp) const { | 318 bool SafeStackFrameIterator::IsValidExitFrame(Address fp) const { |
319 if (!IsValidStackAddress(fp)) return false; | 319 if (!IsValidStackAddress(fp)) return false; |
320 Address sp = ExitFrame::ComputeStackPointer(fp); | 320 Address sp = ExitFrame::ComputeStackPointer(fp); |
321 if (!IsValidStackAddress(sp)) return false; | 321 if (!IsValidStackAddress(sp)) return false; |
322 StackFrame::State state; | 322 StackFrame::State state; |
323 ExitFrame::FillState(fp, sp, &state); | 323 ExitFrame::FillState(fp, sp, &state); |
324 if (!IsValidStackAddress(reinterpret_cast<Address>(state.pc_address))) { | |
325 return false; | |
326 } | |
rmcilroy
2015/04/08 12:38:55
I'm not sure why you are making this change here,
MTBrandyberry
2015/05/07 20:38:32
By definition, the an exit frame's pc_address is a
| |
327 return *state.pc_address != NULL; | 324 return *state.pc_address != NULL; |
328 } | 325 } |
329 | 326 |
330 | 327 |
331 void SafeStackFrameIterator::Advance() { | 328 void SafeStackFrameIterator::Advance() { |
332 while (true) { | 329 while (true) { |
333 AdvanceOneFrame(); | 330 AdvanceOneFrame(); |
334 if (done()) return; | 331 if (done()) return; |
335 if (frame_->is_java_script()) return; | 332 if (frame_->is_java_script()) return; |
336 if (frame_->is_exit() && external_callback_scope_) { | 333 if (frame_->is_exit() && external_callback_scope_) { |
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
378 *stack_slots = code->stack_slots(); | 375 *stack_slots = code->stack_slots(); |
379 return code; | 376 return code; |
380 } | 377 } |
381 | 378 |
382 | 379 |
383 #ifdef DEBUG | 380 #ifdef DEBUG |
384 static bool GcSafeCodeContains(HeapObject* object, Address addr); | 381 static bool GcSafeCodeContains(HeapObject* object, Address addr); |
385 #endif | 382 #endif |
386 | 383 |
387 | 384 |
388 void StackFrame::IteratePc(ObjectVisitor* v, | 385 void StackFrame::IteratePc(ObjectVisitor* v, Address* pc_address, |
389 Address* pc_address, | 386 Address* constant_pool_address, Code* holder) { |
390 Code* holder) { | |
391 Address pc = *pc_address; | 387 Address pc = *pc_address; |
392 DCHECK(GcSafeCodeContains(holder, pc)); | 388 DCHECK(GcSafeCodeContains(holder, pc)); |
393 unsigned pc_offset = static_cast<unsigned>(pc - holder->instruction_start()); | 389 unsigned pc_offset = static_cast<unsigned>(pc - holder->instruction_start()); |
394 Object* code = holder; | 390 Object* code = holder; |
395 v->VisitPointer(&code); | 391 v->VisitPointer(&code); |
396 if (code != holder) { | 392 if (code != holder) { |
397 holder = reinterpret_cast<Code*>(code); | 393 holder = reinterpret_cast<Code*>(code); |
398 pc = holder->instruction_start() + pc_offset; | 394 pc = holder->instruction_start() + pc_offset; |
399 *pc_address = pc; | 395 *pc_address = pc; |
396 if (FLAG_enable_embedded_constant_pool && constant_pool_address) { | |
397 *constant_pool_address = holder->constant_pool(); | |
398 } | |
400 } | 399 } |
401 } | 400 } |
402 | 401 |
403 | 402 |
404 void StackFrame::SetReturnAddressLocationResolver( | 403 void StackFrame::SetReturnAddressLocationResolver( |
405 ReturnAddressLocationResolver resolver) { | 404 ReturnAddressLocationResolver resolver) { |
406 DCHECK(return_address_location_resolver_ == NULL); | 405 DCHECK(return_address_location_resolver_ == NULL); |
407 return_address_location_resolver_ = resolver; | 406 return_address_location_resolver_ = resolver; |
408 } | 407 } |
409 | 408 |
(...skipping 89 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
499 return reinterpret_cast<Code*>(code_slot()); | 498 return reinterpret_cast<Code*>(code_slot()); |
500 } | 499 } |
501 | 500 |
502 | 501 |
503 void ExitFrame::ComputeCallerState(State* state) const { | 502 void ExitFrame::ComputeCallerState(State* state) const { |
504 // Set up the caller state. | 503 // Set up the caller state. |
505 state->sp = caller_sp(); | 504 state->sp = caller_sp(); |
506 state->fp = Memory::Address_at(fp() + ExitFrameConstants::kCallerFPOffset); | 505 state->fp = Memory::Address_at(fp() + ExitFrameConstants::kCallerFPOffset); |
507 state->pc_address = ResolveReturnAddressLocation( | 506 state->pc_address = ResolveReturnAddressLocation( |
508 reinterpret_cast<Address*>(fp() + ExitFrameConstants::kCallerPCOffset)); | 507 reinterpret_cast<Address*>(fp() + ExitFrameConstants::kCallerPCOffset)); |
509 if (FLAG_enable_ool_constant_pool) { | 508 if (FLAG_enable_ool_constant_pool || FLAG_enable_embedded_constant_pool) { |
510 state->constant_pool_address = reinterpret_cast<Address*>( | 509 state->constant_pool_address = reinterpret_cast<Address*>( |
511 fp() + ExitFrameConstants::kConstantPoolOffset); | 510 fp() + ExitFrameConstants::kConstantPoolOffset); |
512 } | 511 } |
513 } | 512 } |
514 | 513 |
515 | 514 |
516 void ExitFrame::SetCallerFp(Address caller_fp) { | 515 void ExitFrame::SetCallerFp(Address caller_fp) { |
517 Memory::Address_at(fp() + ExitFrameConstants::kCallerFPOffset) = caller_fp; | 516 Memory::Address_at(fp() + ExitFrameConstants::kCallerFPOffset) = caller_fp; |
518 } | 517 } |
519 | 518 |
520 | 519 |
521 void ExitFrame::Iterate(ObjectVisitor* v) const { | 520 void ExitFrame::Iterate(ObjectVisitor* v) const { |
522 // The arguments are traversed as part of the expression stack of | 521 // The arguments are traversed as part of the expression stack of |
523 // the calling frame. | 522 // the calling frame. |
524 IteratePc(v, pc_address(), LookupCode()); | 523 IteratePc(v, pc_address(), constant_pool_address(), LookupCode()); |
525 v->VisitPointer(&code_slot()); | 524 v->VisitPointer(&code_slot()); |
526 if (FLAG_enable_ool_constant_pool) { | 525 if (FLAG_enable_ool_constant_pool) { |
527 v->VisitPointer(&constant_pool_slot()); | 526 v->VisitPointer(&constant_pool_slot()); |
528 } | 527 } |
529 } | 528 } |
530 | 529 |
531 | 530 |
532 Address ExitFrame::GetCallerStackPointer() const { | 531 Address ExitFrame::GetCallerStackPointer() const { |
533 return fp() + ExitFrameConstants::kCallerSPDisplacement; | 532 return fp() + ExitFrameConstants::kCallerSPDisplacement; |
534 } | 533 } |
(...skipping 11 matching lines...) Expand all Loading... | |
546 Address ExitFrame::ComputeStackPointer(Address fp) { | 545 Address ExitFrame::ComputeStackPointer(Address fp) { |
547 return Memory::Address_at(fp + ExitFrameConstants::kSPOffset); | 546 return Memory::Address_at(fp + ExitFrameConstants::kSPOffset); |
548 } | 547 } |
549 | 548 |
550 | 549 |
551 void ExitFrame::FillState(Address fp, Address sp, State* state) { | 550 void ExitFrame::FillState(Address fp, Address sp, State* state) { |
552 state->sp = sp; | 551 state->sp = sp; |
553 state->fp = fp; | 552 state->fp = fp; |
554 state->pc_address = ResolveReturnAddressLocation( | 553 state->pc_address = ResolveReturnAddressLocation( |
555 reinterpret_cast<Address*>(sp - 1 * kPCOnStackSize)); | 554 reinterpret_cast<Address*>(sp - 1 * kPCOnStackSize)); |
556 state->constant_pool_address = | 555 // The constant pool recorded in the exit frame is not associated |
557 reinterpret_cast<Address*>(fp + ExitFrameConstants::kConstantPoolOffset); | 556 // with the pc in this state (the return address into a C entry |
557 // stub). ComputeCallerState will retrieve the constant pool | |
558 // together with the associated caller pc. | |
559 state->constant_pool_address = NULL; | |
558 } | 560 } |
559 | 561 |
560 | 562 |
561 Address StandardFrame::GetExpressionAddress(int n) const { | 563 Address StandardFrame::GetExpressionAddress(int n) const { |
562 const int offset = StandardFrameConstants::kExpressionsOffset; | 564 const int offset = StandardFrameConstants::kExpressionsOffset; |
563 return fp() + offset - n * kPointerSize; | 565 return fp() + offset - n * kPointerSize; |
564 } | 566 } |
565 | 567 |
566 | 568 |
567 Object* StandardFrame::GetExpression(Address fp, int index) { | 569 Object* StandardFrame::GetExpression(Address fp, int index) { |
(...skipping 88 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
656 // Visit pointer spill slots and locals. | 658 // Visit pointer spill slots and locals. |
657 for (unsigned index = 0; index < stack_slots; index++) { | 659 for (unsigned index = 0; index < stack_slots; index++) { |
658 int byte_index = index >> kBitsPerByteLog2; | 660 int byte_index = index >> kBitsPerByteLog2; |
659 int bit_index = index & (kBitsPerByte - 1); | 661 int bit_index = index & (kBitsPerByte - 1); |
660 if ((safepoint_bits[byte_index] & (1U << bit_index)) != 0) { | 662 if ((safepoint_bits[byte_index] & (1U << bit_index)) != 0) { |
661 v->VisitPointer(parameters_limit + index); | 663 v->VisitPointer(parameters_limit + index); |
662 } | 664 } |
663 } | 665 } |
664 | 666 |
665 // Visit the return address in the callee and incoming arguments. | 667 // Visit the return address in the callee and incoming arguments. |
666 IteratePc(v, pc_address(), code); | 668 IteratePc(v, pc_address(), constant_pool_address(), code); |
667 | 669 |
668 // Visit the context in stub frame and JavaScript frame. | 670 // Visit the context in stub frame and JavaScript frame. |
669 // Visit the function in JavaScript frame. | 671 // Visit the function in JavaScript frame. |
670 Object** fixed_base = &Memory::Object_at( | 672 Object** fixed_base = &Memory::Object_at( |
671 fp() + StandardFrameConstants::kMarkerOffset); | 673 fp() + StandardFrameConstants::kMarkerOffset); |
672 Object** fixed_limit = &Memory::Object_at(fp()); | 674 Object** fixed_limit = &Memory::Object_at(fp()); |
673 v->VisitPointers(fixed_base, fixed_limit); | 675 v->VisitPointers(fixed_base, fixed_limit); |
674 } | 676 } |
675 | 677 |
676 | 678 |
(...skipping 601 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1278 accumulator->Add(" // not passed to callee"); | 1280 accumulator->Add(" // not passed to callee"); |
1279 } | 1281 } |
1280 accumulator->Add("\n"); | 1282 accumulator->Add("\n"); |
1281 } | 1283 } |
1282 | 1284 |
1283 accumulator->Add("}\n\n"); | 1285 accumulator->Add("}\n\n"); |
1284 } | 1286 } |
1285 | 1287 |
1286 | 1288 |
1287 void EntryFrame::Iterate(ObjectVisitor* v) const { | 1289 void EntryFrame::Iterate(ObjectVisitor* v) const { |
1288 IteratePc(v, pc_address(), LookupCode()); | 1290 IteratePc(v, pc_address(), constant_pool_address(), LookupCode()); |
1289 } | 1291 } |
1290 | 1292 |
1291 | 1293 |
1292 void StandardFrame::IterateExpressions(ObjectVisitor* v) const { | 1294 void StandardFrame::IterateExpressions(ObjectVisitor* v) const { |
1293 const int offset = StandardFrameConstants::kLastObjectOffset; | 1295 const int offset = StandardFrameConstants::kLastObjectOffset; |
1294 Object** base = &Memory::Object_at(sp()); | 1296 Object** base = &Memory::Object_at(sp()); |
1295 Object** limit = &Memory::Object_at(fp() + offset) + 1; | 1297 Object** limit = &Memory::Object_at(fp() + offset) + 1; |
1296 v->VisitPointers(base, limit); | 1298 v->VisitPointers(base, limit); |
1297 } | 1299 } |
1298 | 1300 |
1299 | 1301 |
1300 void JavaScriptFrame::Iterate(ObjectVisitor* v) const { | 1302 void JavaScriptFrame::Iterate(ObjectVisitor* v) const { |
1301 IterateExpressions(v); | 1303 IterateExpressions(v); |
1302 IteratePc(v, pc_address(), LookupCode()); | 1304 IteratePc(v, pc_address(), constant_pool_address(), LookupCode()); |
1303 } | 1305 } |
1304 | 1306 |
1305 | 1307 |
1306 void InternalFrame::Iterate(ObjectVisitor* v) const { | 1308 void InternalFrame::Iterate(ObjectVisitor* v) const { |
1307 // Internal frames only have object pointers on the expression stack | 1309 // Internal frames only have object pointers on the expression stack |
1308 // as they never have any arguments. | 1310 // as they never have any arguments. |
1309 IterateExpressions(v); | 1311 IterateExpressions(v); |
1310 IteratePc(v, pc_address(), LookupCode()); | 1312 IteratePc(v, pc_address(), constant_pool_address(), LookupCode()); |
1311 } | 1313 } |
1312 | 1314 |
1313 | 1315 |
1314 void StubFailureTrampolineFrame::Iterate(ObjectVisitor* v) const { | 1316 void StubFailureTrampolineFrame::Iterate(ObjectVisitor* v) const { |
1315 Object** base = &Memory::Object_at(sp()); | 1317 Object** base = &Memory::Object_at(sp()); |
1316 Object** limit = &Memory::Object_at(fp() + | 1318 Object** limit = &Memory::Object_at(fp() + |
1317 kFirstRegisterParameterFrameOffset); | 1319 kFirstRegisterParameterFrameOffset); |
1318 v->VisitPointers(base, limit); | 1320 v->VisitPointers(base, limit); |
1319 base = &Memory::Object_at(fp() + StandardFrameConstants::kMarkerOffset); | 1321 base = &Memory::Object_at(fp() + StandardFrameConstants::kMarkerOffset); |
1320 const int offset = StandardFrameConstants::kLastObjectOffset; | 1322 const int offset = StandardFrameConstants::kLastObjectOffset; |
1321 limit = &Memory::Object_at(fp() + offset) + 1; | 1323 limit = &Memory::Object_at(fp() + offset) + 1; |
1322 v->VisitPointers(base, limit); | 1324 v->VisitPointers(base, limit); |
1323 IteratePc(v, pc_address(), LookupCode()); | 1325 IteratePc(v, pc_address(), constant_pool_address(), LookupCode()); |
1324 } | 1326 } |
1325 | 1327 |
1326 | 1328 |
1327 Address StubFailureTrampolineFrame::GetCallerStackPointer() const { | 1329 Address StubFailureTrampolineFrame::GetCallerStackPointer() const { |
1328 return fp() + StandardFrameConstants::kCallerSPOffset; | 1330 return fp() + StandardFrameConstants::kCallerSPOffset; |
1329 } | 1331 } |
1330 | 1332 |
1331 | 1333 |
1332 Code* StubFailureTrampolineFrame::unchecked_code() const { | 1334 Code* StubFailureTrampolineFrame::unchecked_code() const { |
1333 Code* trampoline; | 1335 Code* trampoline; |
(...skipping 180 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1514 ZoneList<StackFrame*> list(10, zone); | 1516 ZoneList<StackFrame*> list(10, zone); |
1515 for (StackFrameIterator it(isolate); !it.done(); it.Advance()) { | 1517 for (StackFrameIterator it(isolate); !it.done(); it.Advance()) { |
1516 StackFrame* frame = AllocateFrameCopy(it.frame(), zone); | 1518 StackFrame* frame = AllocateFrameCopy(it.frame(), zone); |
1517 list.Add(frame, zone); | 1519 list.Add(frame, zone); |
1518 } | 1520 } |
1519 return list.ToVector(); | 1521 return list.ToVector(); |
1520 } | 1522 } |
1521 | 1523 |
1522 | 1524 |
1523 } } // namespace v8::internal | 1525 } } // namespace v8::internal |
OLD | NEW |