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

Side by Side Diff: src/frames.cc

Issue 3226014: Add functionality for finding code objects from a pc that points into... (Closed) Base URL: http://v8.googlecode.com/svn/branches/bleeding_edge/
Patch Set: '' Created 10 years, 3 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/frames.h ('k') | src/frames-inl.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 18 matching lines...) Expand all
29 29
30 #include "frames-inl.h" 30 #include "frames-inl.h"
31 #include "mark-compact.h" 31 #include "mark-compact.h"
32 #include "scopeinfo.h" 32 #include "scopeinfo.h"
33 #include "string-stream.h" 33 #include "string-stream.h"
34 #include "top.h" 34 #include "top.h"
35 35
36 namespace v8 { 36 namespace v8 {
37 namespace internal { 37 namespace internal {
38 38
39 PcToCodeCache::PcToCodeCacheEntry
40 PcToCodeCache::cache_[PcToCodeCache::kPcToCodeCacheSize];
41
42 int SafeStackFrameIterator::active_count_ = 0;
43
39 // Iterator that supports traversing the stack handlers of a 44 // Iterator that supports traversing the stack handlers of a
40 // particular frame. Needs to know the top of the handler chain. 45 // particular frame. Needs to know the top of the handler chain.
41 class StackHandlerIterator BASE_EMBEDDED { 46 class StackHandlerIterator BASE_EMBEDDED {
42 public: 47 public:
43 StackHandlerIterator(const StackFrame* frame, StackHandler* handler) 48 StackHandlerIterator(const StackFrame* frame, StackHandler* handler)
44 : limit_(frame->fp()), handler_(handler) { 49 : limit_(frame->fp()), handler_(handler) {
45 // Make sure the handler has already been unwound to this frame. 50 // Make sure the handler has already been unwound to this frame.
46 ASSERT(frame->sp() <= handler->address()); 51 ASSERT(frame->sp() <= handler->address());
47 } 52 }
48 53
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after
81 StackFrameIterator::StackFrameIterator(bool use_top, Address fp, Address sp) 86 StackFrameIterator::StackFrameIterator(bool use_top, Address fp, Address sp)
82 : STACK_FRAME_TYPE_LIST(INITIALIZE_SINGLETON) 87 : STACK_FRAME_TYPE_LIST(INITIALIZE_SINGLETON)
83 frame_(NULL), handler_(NULL), 88 frame_(NULL), handler_(NULL),
84 thread_(use_top ? Top::GetCurrentThread() : NULL), 89 thread_(use_top ? Top::GetCurrentThread() : NULL),
85 fp_(use_top ? NULL : fp), sp_(sp), 90 fp_(use_top ? NULL : fp), sp_(sp),
86 advance_(use_top ? &StackFrameIterator::AdvanceWithHandler : 91 advance_(use_top ? &StackFrameIterator::AdvanceWithHandler :
87 &StackFrameIterator::AdvanceWithoutHandler) { 92 &StackFrameIterator::AdvanceWithoutHandler) {
88 if (use_top || fp != NULL) { 93 if (use_top || fp != NULL) {
89 Reset(); 94 Reset();
90 } 95 }
91 JavaScriptFrame_.DisableHeapAccess();
92 } 96 }
93 97
94 #undef INITIALIZE_SINGLETON 98 #undef INITIALIZE_SINGLETON
95 99
96 100
97 void StackFrameIterator::AdvanceWithHandler() { 101 void StackFrameIterator::AdvanceWithHandler() {
98 ASSERT(!done()); 102 ASSERT(!done());
99 // Compute the state of the calling frame before restoring 103 // Compute the state of the calling frame before restoring
100 // callee-saved registers and unwinding handlers. This allows the 104 // callee-saved registers and unwinding handlers. This allows the
101 // frame code that computes the caller state to access the top 105 // frame code that computes the caller state to access the top
(...skipping 92 matching lines...) Expand 10 before | Expand all | Expand 10 after
194 return (script->IsScript() && 198 return (script->IsScript() &&
195 Script::TYPE_NATIVE != Script::cast(script)->type()->value()); 199 Script::TYPE_NATIVE != Script::cast(script)->type()->value());
196 } 200 }
197 201
198 202
199 // ------------------------------------------------------------------------- 203 // -------------------------------------------------------------------------
200 204
201 205
202 SafeStackFrameIterator::SafeStackFrameIterator( 206 SafeStackFrameIterator::SafeStackFrameIterator(
203 Address fp, Address sp, Address low_bound, Address high_bound) : 207 Address fp, Address sp, Address low_bound, Address high_bound) :
204 low_bound_(low_bound), high_bound_(high_bound), 208 maintainer_(), low_bound_(low_bound), high_bound_(high_bound),
205 is_valid_top_( 209 is_valid_top_(
206 IsWithinBounds(low_bound, high_bound, 210 IsWithinBounds(low_bound, high_bound,
207 Top::c_entry_fp(Top::GetCurrentThread())) && 211 Top::c_entry_fp(Top::GetCurrentThread())) &&
208 Top::handler(Top::GetCurrentThread()) != NULL), 212 Top::handler(Top::GetCurrentThread()) != NULL),
209 is_valid_fp_(IsWithinBounds(low_bound, high_bound, fp)), 213 is_valid_fp_(IsWithinBounds(low_bound, high_bound, fp)),
210 is_working_iterator_(is_valid_top_ || is_valid_fp_), 214 is_working_iterator_(is_valid_top_ || is_valid_fp_),
211 iteration_done_(!is_working_iterator_), 215 iteration_done_(!is_working_iterator_),
212 iterator_(is_valid_top_, is_valid_fp_ ? fp : NULL, sp) { 216 iterator_(is_valid_top_, is_valid_fp_ ? fp : NULL, sp) {
213 } 217 }
214 218
(...skipping 80 matching lines...) Expand 10 before | Expand all | Expand 10 after
295 void SafeStackTraceFrameIterator::Advance() { 299 void SafeStackTraceFrameIterator::Advance() {
296 while (true) { 300 while (true) {
297 SafeJavaScriptFrameIterator::Advance(); 301 SafeJavaScriptFrameIterator::Advance();
298 if (done()) return; 302 if (done()) return;
299 if (frame()->is_java_script()) return; 303 if (frame()->is_java_script()) return;
300 } 304 }
301 } 305 }
302 #endif 306 #endif
303 307
304 308
305 // -------------------------------------------------------------------------
306
307
308 void StackHandler::Cook(Code* code) {
309 ASSERT(code->contains(pc()));
310 set_pc(AddressFrom<Address>(pc() - code->instruction_start()));
311 }
312
313
314 void StackHandler::Uncook(Code* code) {
315 set_pc(code->instruction_start() + OffsetFrom(pc()));
316 ASSERT(code->contains(pc()));
317 }
318
319
320 // -------------------------------------------------------------------------
321
322
323 bool StackFrame::HasHandler() const { 309 bool StackFrame::HasHandler() const {
324 StackHandlerIterator it(this, top_handler()); 310 StackHandlerIterator it(this, top_handler());
325 return !it.done(); 311 return !it.done();
326 } 312 }
327 313
328 314 void StackFrame::IteratePc(ObjectVisitor* v,
329 void StackFrame::CookFramesForThread(ThreadLocalTop* thread) { 315 Address* pc_address,
330 ASSERT(!thread->stack_is_cooked()); 316 Code* holder) {
331 for (StackFrameIterator it(thread); !it.done(); it.Advance()) { 317 Address pc = *pc_address;
332 it.frame()->Cook(); 318 ASSERT(holder->contains(pc));
319 unsigned pc_offset = pc - holder->instruction_start();
320 Object* code = holder;
321 v->VisitPointer(&code);
322 if (code != holder) {
323 holder = reinterpret_cast<Code*>(code);
324 pc = holder->instruction_start() + pc_offset;
325 *pc_address = pc;
333 } 326 }
334 thread->set_stack_is_cooked(true);
335 } 327 }
336 328
337 329
338 void StackFrame::UncookFramesForThread(ThreadLocalTop* thread) { 330 StackFrame::Type StackFrame::ComputeType(State* state) {
339 ASSERT(thread->stack_is_cooked()); 331 ASSERT(state->fp != NULL);
340 for (StackFrameIterator it(thread); !it.done(); it.Advance()) { 332 if (StandardFrame::IsArgumentsAdaptorFrame(state->fp)) {
341 it.frame()->Uncook(); 333 return ARGUMENTS_ADAPTOR;
342 } 334 }
343 thread->set_stack_is_cooked(false); 335 // The marker and function offsets overlap. If the marker isn't a
336 // smi then the frame is a JavaScript frame -- and the marker is
337 // really the function.
338 const int offset = StandardFrameConstants::kMarkerOffset;
339 Object* marker = Memory::Object_at(state->fp + offset);
340 if (!marker->IsSmi()) return JAVA_SCRIPT;
341 return static_cast<StackFrame::Type>(Smi::cast(marker)->value());
344 } 342 }
345 343
346 344
347 void StackFrame::Cook() {
348 Code* code = this->code();
349 ASSERT(code->IsCode());
350 for (StackHandlerIterator it(this, top_handler()); !it.done(); it.Advance()) {
351 it.handler()->Cook(code);
352 }
353 ASSERT(code->contains(pc()));
354 set_pc(AddressFrom<Address>(pc() - code->instruction_start()));
355 }
356
357
358 void StackFrame::Uncook() {
359 Code* code = this->code();
360 ASSERT(code->IsCode());
361 for (StackHandlerIterator it(this, top_handler()); !it.done(); it.Advance()) {
362 it.handler()->Uncook(code);
363 }
364 set_pc(code->instruction_start() + OffsetFrom(pc()));
365 ASSERT(code->contains(pc()));
366 }
367
368 345
369 StackFrame::Type StackFrame::GetCallerState(State* state) const { 346 StackFrame::Type StackFrame::GetCallerState(State* state) const {
370 ComputeCallerState(state); 347 ComputeCallerState(state);
371 return ComputeType(state); 348 return ComputeType(state);
372 } 349 }
373 350
374 351
375 Code* EntryFrame::unchecked_code() const { 352 Code* EntryFrame::unchecked_code() const {
376 return Heap::raw_unchecked_js_entry_code(); 353 return Heap::raw_unchecked_js_entry_code();
377 } 354 }
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after
418 state->pc_address 395 state->pc_address
419 = reinterpret_cast<Address*>(fp() + ExitFrameConstants::kCallerPCOffset); 396 = reinterpret_cast<Address*>(fp() + ExitFrameConstants::kCallerPCOffset);
420 } 397 }
421 398
422 399
423 void ExitFrame::SetCallerFp(Address caller_fp) { 400 void ExitFrame::SetCallerFp(Address caller_fp) {
424 Memory::Address_at(fp() + ExitFrameConstants::kCallerFPOffset) = caller_fp; 401 Memory::Address_at(fp() + ExitFrameConstants::kCallerFPOffset) = caller_fp;
425 } 402 }
426 403
427 404
405 void ExitFrame::Iterate(ObjectVisitor* v) const {
406 // The arguments are traversed as part of the expression stack of
407 // the calling frame.
408 IteratePc(v, pc_address(), code());
409 v->VisitPointer(&code_slot());
410 }
411
412
428 Address ExitFrame::GetCallerStackPointer() const { 413 Address ExitFrame::GetCallerStackPointer() const {
429 return fp() + ExitFrameConstants::kCallerSPDisplacement; 414 return fp() + ExitFrameConstants::kCallerSPDisplacement;
430 } 415 }
431 416
432 417
433 Address StandardFrame::GetExpressionAddress(int n) const { 418 Address StandardFrame::GetExpressionAddress(int n) const {
434 const int offset = StandardFrameConstants::kExpressionsOffset; 419 const int offset = StandardFrameConstants::kExpressionsOffset;
435 return fp() + offset - n * kPointerSize; 420 return fp() + offset - n * kPointerSize;
436 } 421 }
437 422
(...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after
492 return IsConstructFrame(fp); 477 return IsConstructFrame(fp);
493 } 478 }
494 479
495 480
496 Code* JavaScriptFrame::unchecked_code() const { 481 Code* JavaScriptFrame::unchecked_code() const {
497 JSFunction* function = JSFunction::cast(this->function()); 482 JSFunction* function = JSFunction::cast(this->function());
498 return function->unchecked_code(); 483 return function->unchecked_code();
499 } 484 }
500 485
501 486
487 int JavaScriptFrame::GetProvidedParametersCount() const {
488 return ComputeParametersCount();
489 }
490
491
492 Address JavaScriptFrame::GetCallerStackPointer() const {
493 int arguments;
494 if (Heap::gc_state() != Heap::NOT_IN_GC ||
495 SafeStackFrameIterator::is_active()) {
496 // If the we are currently iterating the safe stack the
497 // arguments for frames are traversed as if they were
498 // expression stack elements of the calling frame. The reason for
499 // this rather strange decision is that we cannot access the
500 // function during mark-compact GCs when objects may have been marked.
501 // In fact accessing heap objects (like function->shared() below)
502 // at all during GC is problematic.
503 arguments = 0;
504 } else {
505 // Compute the number of arguments by getting the number of formal
506 // parameters of the function. We must remember to take the
507 // receiver into account (+1).
508 JSFunction* function = JSFunction::cast(this->function());
509 arguments = function->shared()->formal_parameter_count() + 1;
510 }
511 const int offset = StandardFrameConstants::kCallerSPOffset;
512 return fp() + offset + (arguments * kPointerSize);
513 }
514
515
516 Address ArgumentsAdaptorFrame::GetCallerStackPointer() const {
517 const int arguments = Smi::cast(GetExpression(0))->value();
518 const int offset = StandardFrameConstants::kCallerSPOffset;
519 return fp() + offset + (arguments + 1) * kPointerSize;
520 }
521
522
523 Address InternalFrame::GetCallerStackPointer() const {
524 // Internal frames have no arguments. The stack pointer of the
525 // caller is at a fixed offset from the frame pointer.
526 return fp() + StandardFrameConstants::kCallerSPOffset;
527 }
528
529
502 Code* ArgumentsAdaptorFrame::unchecked_code() const { 530 Code* ArgumentsAdaptorFrame::unchecked_code() const {
503 return Builtins::builtin(Builtins::ArgumentsAdaptorTrampoline); 531 return Builtins::builtin(Builtins::ArgumentsAdaptorTrampoline);
504 } 532 }
505 533
506 534
507 Code* InternalFrame::unchecked_code() const { 535 Code* InternalFrame::unchecked_code() const {
508 const int offset = InternalFrameConstants::kCodeOffset; 536 const int offset = InternalFrameConstants::kCodeOffset;
509 Object* code = Memory::Object_at(fp() + offset); 537 Object* code = Memory::Object_at(fp() + offset);
510 ASSERT(code != NULL); 538 ASSERT(code != NULL);
511 return reinterpret_cast<Code*>(code); 539 return reinterpret_cast<Code*>(code);
(...skipping 175 matching lines...) Expand 10 before | Expand all | Expand 10 after
687 715
688 accumulator->Add("}\n\n"); 716 accumulator->Add("}\n\n");
689 } 717 }
690 718
691 719
692 void EntryFrame::Iterate(ObjectVisitor* v) const { 720 void EntryFrame::Iterate(ObjectVisitor* v) const {
693 StackHandlerIterator it(this, top_handler()); 721 StackHandlerIterator it(this, top_handler());
694 ASSERT(!it.done()); 722 ASSERT(!it.done());
695 StackHandler* handler = it.handler(); 723 StackHandler* handler = it.handler();
696 ASSERT(handler->is_entry()); 724 ASSERT(handler->is_entry());
697 handler->Iterate(v); 725 handler->Iterate(v, code());
698 // Make sure that there's the entry frame does not contain more than
699 // one stack handler.
700 #ifdef DEBUG 726 #ifdef DEBUG
727 // Make sure that the entry frame does not contain more than one
728 // stack handler.
701 it.Advance(); 729 it.Advance();
702 ASSERT(it.done()); 730 ASSERT(it.done());
703 #endif 731 #endif
732 IteratePc(v, pc_address(), code());
704 } 733 }
705 734
706 735
707 void StandardFrame::IterateExpressions(ObjectVisitor* v) const { 736 void StandardFrame::IterateExpressions(ObjectVisitor* v) const {
708 const int offset = StandardFrameConstants::kContextOffset; 737 const int offset = StandardFrameConstants::kContextOffset;
709 Object** base = &Memory::Object_at(sp()); 738 Object** base = &Memory::Object_at(sp());
710 Object** limit = &Memory::Object_at(fp() + offset) + 1; 739 Object** limit = &Memory::Object_at(fp() + offset) + 1;
711 for (StackHandlerIterator it(this, top_handler()); !it.done(); it.Advance()) { 740 for (StackHandlerIterator it(this, top_handler()); !it.done(); it.Advance()) {
712 StackHandler* handler = it.handler(); 741 StackHandler* handler = it.handler();
713 // Traverse pointers down to - but not including - the next 742 // Traverse pointers down to - but not including - the next
714 // handler in the handler chain. Update the base to skip the 743 // handler in the handler chain. Update the base to skip the
715 // handler and allow the handler to traverse its own pointers. 744 // handler and allow the handler to traverse its own pointers.
716 const Address address = handler->address(); 745 const Address address = handler->address();
717 v->VisitPointers(base, reinterpret_cast<Object**>(address)); 746 v->VisitPointers(base, reinterpret_cast<Object**>(address));
718 base = reinterpret_cast<Object**>(address + StackHandlerConstants::kSize); 747 base = reinterpret_cast<Object**>(address + StackHandlerConstants::kSize);
719 // Traverse the pointers in the handler itself. 748 // Traverse the pointers in the handler itself.
720 handler->Iterate(v); 749 handler->Iterate(v, code());
721 } 750 }
722 v->VisitPointers(base, limit); 751 v->VisitPointers(base, limit);
723 } 752 }
724 753
725 754
726 void JavaScriptFrame::Iterate(ObjectVisitor* v) const { 755 void JavaScriptFrame::Iterate(ObjectVisitor* v) const {
727 IterateExpressions(v); 756 IterateExpressions(v);
757 IteratePc(v, pc_address(), code());
728 758
729 // Traverse callee-saved registers, receiver, and parameters. 759 // Traverse callee-saved registers, receiver, and parameters.
730 const int kBaseOffset = JavaScriptFrameConstants::kSavedRegistersOffset; 760 const int kBaseOffset = JavaScriptFrameConstants::kSavedRegistersOffset;
731 const int kLimitOffset = JavaScriptFrameConstants::kReceiverOffset; 761 const int kLimitOffset = JavaScriptFrameConstants::kReceiverOffset;
732 Object** base = &Memory::Object_at(fp() + kBaseOffset); 762 Object** base = &Memory::Object_at(fp() + kBaseOffset);
733 Object** limit = &Memory::Object_at(caller_sp() + kLimitOffset) + 1; 763 Object** limit = &Memory::Object_at(caller_sp() + kLimitOffset) + 1;
734 v->VisitPointers(base, limit); 764 v->VisitPointers(base, limit);
735 } 765 }
736 766
737 767
738 void InternalFrame::Iterate(ObjectVisitor* v) const { 768 void InternalFrame::Iterate(ObjectVisitor* v) const {
739 // Internal frames only have object pointers on the expression stack 769 // Internal frames only have object pointers on the expression stack
740 // as they never have any arguments. 770 // as they never have any arguments.
741 IterateExpressions(v); 771 IterateExpressions(v);
772 IteratePc(v, pc_address(), code());
742 } 773 }
743 774
744 775
745 // ------------------------------------------------------------------------- 776 // -------------------------------------------------------------------------
746 777
747 778
748 JavaScriptFrame* StackFrameLocator::FindJavaScriptFrame(int n) { 779 JavaScriptFrame* StackFrameLocator::FindJavaScriptFrame(int n) {
749 ASSERT(n >= 0); 780 ASSERT(n >= 0);
750 for (int i = 0; i <= n; i++) { 781 for (int i = 0; i <= n; i++) {
751 while (!iterator_.frame()->is_java_script()) iterator_.Advance(); 782 while (!iterator_.frame()->is_java_script()) iterator_.Advance();
752 if (i == n) return JavaScriptFrame::cast(iterator_.frame()); 783 if (i == n) return JavaScriptFrame::cast(iterator_.frame());
753 iterator_.Advance(); 784 iterator_.Advance();
754 } 785 }
755 UNREACHABLE(); 786 UNREACHABLE();
756 return NULL; 787 return NULL;
757 } 788 }
758 789
759 790
760 // ------------------------------------------------------------------------- 791 // -------------------------------------------------------------------------
761 792
762 793
794 Code* PcToCodeCache::GcSafeCastToCode(HeapObject* object, Address pc) {
795 Code* code = reinterpret_cast<Code*>(object);
796 ASSERT(code != NULL && code->contains(pc));
797 return code;
798 }
799
800
801 Code* PcToCodeCache::GcSafeFindCodeForPc(Address pc) {
802 // Check if the pc points into a large object chunk.
803 LargeObjectChunk* chunk = Heap::lo_space()->FindChunkContainingPc(pc);
804 if (chunk != NULL) return GcSafeCastToCode(chunk->GetObject(), pc);
805
806 // Iterate through the 8K page until we reach the end or find an
807 // object starting after the pc.
808 Page* page = Page::FromAddress(pc);
809 HeapObjectIterator iterator(page, Heap::GcSafeSizeOfOldObjectFunction());
810 HeapObject* previous = NULL;
811 while (true) {
812 HeapObject* next = iterator.next();
813 if (next == NULL || next->address() >= pc) {
814 return GcSafeCastToCode(previous, pc);
815 }
816 previous = next;
817 }
818 }
819
820 PcToCodeCache::PcToCodeCacheEntry* PcToCodeCache::GetCacheEntry(Address pc) {
821 Counters::pc_to_code.Increment();
822 ASSERT(IsPowerOf2(kPcToCodeCacheSize));
823 uint32_t hash = ComputeIntegerHash(
824 static_cast<uint32_t>(reinterpret_cast<uintptr_t>(pc)));
825 uint32_t index = hash & (kPcToCodeCacheSize - 1);
826 PcToCodeCacheEntry* entry = cache(index);
827 if (entry->pc == pc) {
828 Counters::pc_to_code_cached.Increment();
829 ASSERT(entry->code == GcSafeFindCodeForPc(pc));
830 } else {
831 // Because this code may be interrupted by a profiling signal that
832 // also queries the cache, we cannot update pc before the code has
833 // been set. Otherwise, we risk trying to use a cache entry before
834 // the code has been computed.
835 entry->code = GcSafeFindCodeForPc(pc);
836 entry->pc = pc;
837 }
838 return entry;
839 }
840
841
842 // -------------------------------------------------------------------------
843
763 int NumRegs(RegList reglist) { 844 int NumRegs(RegList reglist) {
764 int n = 0; 845 int n = 0;
765 while (reglist != 0) { 846 while (reglist != 0) {
766 n++; 847 n++;
767 reglist &= reglist - 1; // clear one bit 848 reglist &= reglist - 1; // clear one bit
768 } 849 }
769 return n; 850 return n;
770 } 851 }
771 852
772 853
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after
817 ZoneList<StackFrame*> list(10); 898 ZoneList<StackFrame*> list(10);
818 for (StackFrameIterator it; !it.done(); it.Advance()) { 899 for (StackFrameIterator it; !it.done(); it.Advance()) {
819 StackFrame* frame = AllocateFrameCopy(it.frame()); 900 StackFrame* frame = AllocateFrameCopy(it.frame());
820 list.Add(frame); 901 list.Add(frame);
821 } 902 }
822 return list.ToVector(); 903 return list.ToVector();
823 } 904 }
824 905
825 906
826 } } // namespace v8::internal 907 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « src/frames.h ('k') | src/frames-inl.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698