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

Side by Side Diff: src/runtime.cc

Issue 7523027: Provisional implementation of stack allocated catch variables. Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Created 9 years, 4 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/rewriter.cc ('k') | src/scopeinfo.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 2011 the V8 project authors. All rights reserved. 1 // Copyright 2011 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 10201 matching lines...) Expand 10 before | Expand all | Expand 10 after
10212 10212
10213 // Get the locals names and values into a temporary array. 10213 // Get the locals names and values into a temporary array.
10214 // 10214 //
10215 // TODO(1240907): Hide compiler-introduced stack variables 10215 // TODO(1240907): Hide compiler-introduced stack variables
10216 // (e.g. .result)? For users of the debugger, they will probably be 10216 // (e.g. .result)? For users of the debugger, they will probably be
10217 // confusing. 10217 // confusing.
10218 Handle<FixedArray> locals = 10218 Handle<FixedArray> locals =
10219 isolate->factory()->NewFixedArray(info.NumberOfLocals() * 2); 10219 isolate->factory()->NewFixedArray(info.NumberOfLocals() * 2);
10220 10220
10221 // Fill in the values of the locals. 10221 // Fill in the values of the locals.
10222 int first_stack_index = info.first_stack_index();
10222 int i = 0; 10223 int i = 0;
10223 for (; i < info.number_of_stack_slots(); ++i) { 10224 for (; i < info.number_of_stack_slots(); ++i) {
10224 // Use the value from the stack. 10225 // Use the value from the stack.
10225 locals->set(i * 2, *info.LocalName(i)); 10226 locals->set(i * 2, *info.LocalName(i));
10226 locals->set(i * 2 + 1, frame_inspector.GetExpression(i)); 10227 locals->set(i * 2 + 1,
10228 frame_inspector.GetExpression(i + first_stack_index));
10227 } 10229 }
10228 if (i < info.NumberOfLocals()) { 10230 if (i < info.NumberOfLocals()) {
10229 // Get the context containing declarations. 10231 // Get the context containing declarations.
10230 Handle<Context> context( 10232 Handle<Context> context(
10231 Context::cast(it.frame()->context())->declaration_context()); 10233 Context::cast(it.frame()->context())->declaration_context());
10232 for (; i < info.NumberOfLocals(); ++i) { 10234 for (; i < info.NumberOfLocals(); ++i) {
10233 Handle<String> name = info.LocalName(i); 10235 Handle<String> name = info.LocalName(i);
10234 locals->set(i * 2, *name); 10236 locals->set(i * 2, *name);
10235 locals->set(i * 2 + 1, 10237 locals->set(i * 2 + 1,
10236 context->get(scope_info->ContextSlotIndex(*name, NULL))); 10238 context->get(scope_info->ContextSlotIndex(*name, NULL)));
(...skipping 212 matching lines...) Expand 10 before | Expand all | Expand 10 after
10449 isolate, 10451 isolate,
10450 SetProperty(local_scope, 10452 SetProperty(local_scope,
10451 scope_info.parameter_name(i), 10453 scope_info.parameter_name(i),
10452 Handle<Object>(frame_inspector.GetParameter(i)), 10454 Handle<Object>(frame_inspector.GetParameter(i)),
10453 NONE, 10455 NONE,
10454 kNonStrictMode), 10456 kNonStrictMode),
10455 Handle<JSObject>()); 10457 Handle<JSObject>());
10456 } 10458 }
10457 10459
10458 // Second fill all stack locals. 10460 // Second fill all stack locals.
10461 int first_stack_index = scope_info.first_stack_index();
10459 for (int i = 0; i < scope_info.number_of_stack_slots(); ++i) { 10462 for (int i = 0; i < scope_info.number_of_stack_slots(); ++i) {
10463 int index = i + first_stack_index;
10460 RETURN_IF_EMPTY_HANDLE_VALUE( 10464 RETURN_IF_EMPTY_HANDLE_VALUE(
10461 isolate, 10465 isolate,
10462 SetProperty(local_scope, 10466 SetProperty(local_scope,
10463 scope_info.stack_slot_name(i), 10467 scope_info.stack_slot_name(i),
10464 Handle<Object>(frame_inspector.GetExpression(i)), 10468 Handle<Object>(frame_inspector.GetExpression(index)),
10465 NONE, 10469 NONE,
10466 kNonStrictMode), 10470 kNonStrictMode),
10467 Handle<JSObject>()); 10471 Handle<JSObject>());
10468 } 10472 }
10469 10473
10470 if (scope_info.number_of_context_slots() > Context::MIN_CONTEXT_SLOTS) { 10474 if (scope_info.number_of_context_slots() > Context::MIN_CONTEXT_SLOTS) {
10471 // Third fill all context locals. 10475 // Third fill all context locals.
10472 Handle<Context> frame_context(Context::cast(frame->context())); 10476 Handle<Context> frame_context(Context::cast(frame->context()));
10473 Handle<Context> function_context(frame_context->declaration_context()); 10477 Handle<Context> function_context(frame_context->declaration_context());
10474 if (!CopyContextLocalsToScopeObject(isolate, 10478 if (!CopyContextLocalsToScopeObject(isolate,
(...skipping 86 matching lines...) Expand 10 before | Expand all | Expand 10 after
10561 Handle<JSObject> catch_scope = 10565 Handle<JSObject> catch_scope =
10562 isolate->factory()->NewJSObject(isolate->object_function()); 10566 isolate->factory()->NewJSObject(isolate->object_function());
10563 RETURN_IF_EMPTY_HANDLE_VALUE( 10567 RETURN_IF_EMPTY_HANDLE_VALUE(
10564 isolate, 10568 isolate,
10565 SetProperty(catch_scope, name, thrown_object, NONE, kNonStrictMode), 10569 SetProperty(catch_scope, name, thrown_object, NONE, kNonStrictMode),
10566 Handle<JSObject>()); 10570 Handle<JSObject>());
10567 return catch_scope; 10571 return catch_scope;
10568 } 10572 }
10569 10573
10570 10574
10575
10576 // Create a plain JSObject which materializes the local scope for the specified
10577 // frame.
10578 static Handle<JSObject> MaterializeLocalScope(
10579 Isolate* isolate,
10580 Handle<Context> context,
10581 Handle<SerializedScopeInfo> serialized_scope_info,
10582 JavaScriptFrame* frame,
10583 int inlined_frame_index) {
10584 Handle<JSFunction> function(JSFunction::cast(frame->function()));
10585 ScopeInfo<> scope_info(*serialized_scope_info);
10586 FrameInspector frame_inspector(frame, inlined_frame_index, isolate);
10587
10588 // Allocate and initialize a JSObject with all the arguments, stack locals
10589 // heap locals and extension properties of the debugged function.
10590 Handle<JSObject> local_scope =
10591 isolate->factory()->NewJSObject(isolate->object_function());
10592
10593 // First fill all parameters.
10594 for (int i = 0; i < scope_info.number_of_parameters(); ++i) {
10595 RETURN_IF_EMPTY_HANDLE_VALUE(
10596 isolate,
10597 SetProperty(local_scope,
10598 scope_info.parameter_name(i),
10599 Handle<Object>(frame_inspector.GetParameter(i)),
10600 NONE,
10601 kNonStrictMode),
10602 Handle<JSObject>());
10603 }
10604
10605 // Second fill all stack locals.
10606 int first_stack_index = scope_info.first_stack_index();
10607 for (int i = 0; i < scope_info.number_of_stack_slots(); ++i) {
10608 int index = i + first_stack_index;
10609 RETURN_IF_EMPTY_HANDLE_VALUE(
10610 isolate,
10611 SetProperty(local_scope,
10612 scope_info.stack_slot_name(i),
10613 Handle<Object>(frame_inspector.GetExpression(index)),
10614 NONE,
10615 kNonStrictMode),
10616 Handle<JSObject>());
10617 }
10618
10619 if (scope_info.number_of_context_slots() > Context::MIN_CONTEXT_SLOTS) {
10620 // Third fill all context locals.
10621 Handle<Context> frame_context(Context::cast(frame->context()));
10622 Handle<Context> function_context(frame_context->declaration_context());
10623 if (!CopyContextLocalsToScopeObject(isolate,
10624 serialized_scope_info, scope_info,
10625 function_context, local_scope)) {
10626 return Handle<JSObject>();
10627 }
10628
10629 // Finally copy any properties from the function context extension.
10630 // These will be variables introduced by eval.
10631 if (function_context->closure() == *function) {
10632 if (function_context->has_extension() &&
10633 !function_context->IsGlobalContext()) {
10634 Handle<JSObject> ext(JSObject::cast(function_context->extension()));
10635 Handle<FixedArray> keys = GetKeysInFixedArrayFor(ext, INCLUDE_PROTOS);
10636 for (int i = 0; i < keys->length(); i++) {
10637 // Names of variables introduced by eval are strings.
10638 ASSERT(keys->get(i)->IsString());
10639 Handle<String> key(String::cast(keys->get(i)));
10640 RETURN_IF_EMPTY_HANDLE_VALUE(
10641 isolate,
10642 SetProperty(local_scope,
10643 key,
10644 GetProperty(ext, key),
10645 NONE,
10646 kNonStrictMode),
10647 Handle<JSObject>());
10648 }
10649 }
10650 }
10651 }
10652
10653 return local_scope;
10654 }
10655
10656
10571 // Iterate over the actual scopes visible from a stack frame. All scopes are 10657 // Iterate over the actual scopes visible from a stack frame. All scopes are
10572 // backed by an actual context except the local scope, which is inserted 10658 // backed by an actual context except the local scope, which is inserted
10573 // "artifically" in the context chain. 10659 // "artifically" in the context chain.
10574 class ScopeIterator { 10660 class ScopeIterator {
10575 public: 10661 public:
10576 enum ScopeType { 10662 enum ScopeType {
10577 ScopeTypeGlobal = 0, 10663 ScopeTypeGlobal = 0,
10578 ScopeTypeLocal, 10664 ScopeTypeLocal,
10579 ScopeTypeWith, 10665 ScopeTypeWith,
10580 ScopeTypeClosure, 10666 ScopeTypeClosure,
10581 ScopeTypeCatch 10667 ScopeTypeCatch
10582 }; 10668 };
10583 10669
10584 ScopeIterator(Isolate* isolate, 10670 ScopeIterator(Isolate* isolate,
10585 JavaScriptFrame* frame, 10671 JavaScriptFrame* frame,
10586 int inlined_frame_index) 10672 int inlined_frame_index)
10587 : isolate_(isolate), 10673 : isolate_(isolate),
10588 frame_(frame), 10674 frame_(frame),
10589 inlined_frame_index_(inlined_frame_index), 10675 inlined_frame_index_(inlined_frame_index),
10590 function_(JSFunction::cast(frame->function())), 10676 function_(JSFunction::cast(frame->function())),
10591 context_(Context::cast(frame->context())), 10677 context_(Context::cast(frame->context())),
10592 local_done_(false), 10678 local_scope_chain_(4) {
10593 at_local_(false) {
10594 10679
10595 // Check whether the first scope is actually a local scope. 10680 Handle<SerializedScopeInfo> scope_info(function_->shared()->scope_info());
10596 if (context_->IsGlobalContext()) { 10681 int statement_position =
10597 // If there is a stack slot for .result then this local scope has been 10682 function_->code()->SourceStatementPosition(frame_->pc());
10598 // created for evaluating top level code and it is not a real local scope. 10683 scope_info->GetLocalScopeChain(&local_scope_chain_, statement_position);
10599 // Checking for the existence of .result seems fragile, but the scope info 10684
10600 // saved with the code object does not otherwise have that information. 10685 if (!local_scope_chain_.is_empty()) return;
10601 int index = function_->shared()->scope_info()->
10602 StackSlotIndex(isolate_->heap()->result_symbol());
10603 at_local_ = index < 0;
10604 } else if (context_->IsFunctionContext()) {
10605 at_local_ = true;
10606 } else if (context_->closure() != *function_) {
10607 // The context_ is a with or catch block from the outer function.
10608 ASSERT(context_->IsWithContext() || context_->IsCatchContext());
10609 at_local_ = true;
10610 }
10611 } 10686 }
10612 10687
10613 // More scopes? 10688 // More scopes?
10614 bool Done() { return context_.is_null(); } 10689 bool Done() { return context_.is_null(); }
10615 10690
10616 // Move to the next scope. 10691 private:
10617 void Next() { 10692 void AdvanceContext() {
10618 // If at a local scope mark the local scope as passed.
10619 if (at_local_) {
10620 at_local_ = false;
10621 local_done_ = true;
10622
10623 // If the current context is not associated with the local scope the
10624 // current context is the next real scope, so don't move to the next
10625 // context in this case.
10626 if (context_->closure() != *function_) {
10627 return;
10628 }
10629 }
10630
10631 // The global scope is always the last in the chain. 10693 // The global scope is always the last in the chain.
10632 if (context_->IsGlobalContext()) { 10694 if (context_->IsGlobalContext()) {
10633 context_ = Handle<Context>(); 10695 context_ = Handle<Context>();
10634 return; 10696 return;
10635 } 10697 }
10698 context_ = Handle<Context>(context_->previous(), isolate_);
10699 }
10636 10700
10637 // Move to the next context. 10701 public:
10638 context_ = Handle<Context>(context_->previous(), isolate_); 10702 // Move to the next scope.
10639 10703 void Next() {
10640 // If passing the local scope indicate that the current scope is now the 10704 // Move to the next scope.
10641 // local scope. 10705 if (local_scope_chain_.is_empty()) {
10642 if (!local_done_ && 10706 AdvanceContext();
10643 (context_->IsGlobalContext() || context_->IsFunctionContext())) { 10707 } else {
10644 at_local_ = true; 10708 if (local_scope_chain_.last()->HasContext()) {
10709 AdvanceContext();
10710 }
10711 local_scope_chain_.RemoveLast();
10645 } 10712 }
10646 } 10713 }
10647 10714
10648 // Return the type of the current scope. 10715 // Return the type of the current scope.
10649 int Type() { 10716 int Type() {
10650 if (at_local_) { 10717 if (!local_scope_chain_.is_empty()) {
10651 return ScopeTypeLocal; 10718 Handle<SerializedScopeInfo> scope_info = local_scope_chain_.last();
10719 if (scope_info->ScopeType() == Scope::FUNCTION_SCOPE) {
10720 // If there is a stack slot for .result then this local scope has been
10721 // created for evaluating top level code and it is not a real local
10722 // scope. Checking for the existence of .result seems fragile, but the
10723 // scope info saved with the code object does not otherwise have that
10724 // information.
10725 int index =
10726 scope_info->StackSlotIndex(isolate_->heap()->result_symbol());
10727 if (index >= 0) {
10728 ASSERT(context_->IsGlobalContext());
10729 return ScopeTypeGlobal;
10730 }
10731 ASSERT(context_->IsFunctionContext() ||
10732 !scope_info->HasContext());
10733 return ScopeTypeLocal;
10734 } else if (scope_info->ScopeType() == Scope::GLOBAL_SCOPE) {
10735 ASSERT(context_->IsGlobalContext());
10736 return ScopeTypeGlobal;
10737 } else if (scope_info->ScopeType() == Scope::CATCH_SCOPE) {
10738 ASSERT(context_->IsCatchContext() ||
10739 !scope_info->HasContext());
10740 return ScopeTypeCatch;
10741 } else {
10742 ASSERT(scope_info->ScopeType() == Scope::WITH_SCOPE);
10743 ASSERT(context_->IsWithContext());
10744 return ScopeTypeWith;
10745 }
10652 } 10746 }
10653 if (context_->IsGlobalContext()) { 10747 if (context_->IsGlobalContext()) {
10654 ASSERT(context_->global()->IsGlobalObject()); 10748 ASSERT(context_->global()->IsGlobalObject());
10655 return ScopeTypeGlobal; 10749 return ScopeTypeGlobal;
10656 } 10750 }
10657 if (context_->IsFunctionContext()) { 10751 if (context_->IsFunctionContext()) {
10658 return ScopeTypeClosure; 10752 return ScopeTypeClosure;
10659 } 10753 }
10660 if (context_->IsCatchContext()) { 10754 if (context_->IsCatchContext()) {
10661 return ScopeTypeCatch; 10755 return ScopeTypeCatch;
10662 } 10756 }
10663 ASSERT(context_->IsWithContext()); 10757 ASSERT(context_->IsWithContext());
10664 return ScopeTypeWith; 10758 return ScopeTypeWith;
10665 } 10759 }
10666 10760
10667 // Return the JavaScript object with the content of the current scope. 10761 // Return the JavaScript object with the content of the current scope.
10668 Handle<JSObject> ScopeObject() { 10762 Handle<JSObject> ScopeObject() {
10669 switch (Type()) { 10763 switch (Type()) {
10670 case ScopeIterator::ScopeTypeGlobal: 10764 case ScopeIterator::ScopeTypeGlobal:
10765 if (CurrentContext().is_null()) {
10766 return Handle<JSObject>();
10767 }
10671 return Handle<JSObject>(CurrentContext()->global()); 10768 return Handle<JSObject>(CurrentContext()->global());
10672 case ScopeIterator::ScopeTypeLocal: 10769 case ScopeIterator::ScopeTypeLocal:
10673 // Materialize the content of the local scope into a JSObject. 10770 // Materialize the content of the local scope into a JSObject.
10674 return MaterializeLocalScope(isolate_, frame_, inlined_frame_index_); 10771 ASSERT(local_scope_chain_.length() == 1);
10772 return MaterializeLocalScope(isolate_,
10773 CurrentContext(),
10774 local_scope_chain_.last(),
10775 frame_,
10776 inlined_frame_index_);
10675 case ScopeIterator::ScopeTypeWith: 10777 case ScopeIterator::ScopeTypeWith:
10676 // Return the with object. 10778 // Return the with object.
10677 return Handle<JSObject>(JSObject::cast(CurrentContext()->extension())); 10779 return Handle<JSObject>(JSObject::cast(CurrentContext()->extension()));
10678 case ScopeIterator::ScopeTypeCatch: 10780 case ScopeIterator::ScopeTypeCatch:
10679 return MaterializeCatchScope(isolate_, CurrentContext()); 10781 if (local_scope_chain_.is_empty()) {
10782 return MaterializeCatchScope(isolate_, CurrentContext());
10783 } else {
10784 return MaterializeLocalScope(isolate_,
10785 CurrentContext(),
10786 local_scope_chain_.last(),
10787 frame_,
10788 inlined_frame_index_);
10789 }
10680 case ScopeIterator::ScopeTypeClosure: 10790 case ScopeIterator::ScopeTypeClosure:
10681 // Materialize the content of the closure scope into a JSObject. 10791 // Materialize the content of the closure scope into a JSObject.
10682 return MaterializeClosure(isolate_, CurrentContext()); 10792 return MaterializeClosure(isolate_, CurrentContext());
10683 } 10793 }
10684 UNREACHABLE(); 10794 UNREACHABLE();
10685 return Handle<JSObject>(); 10795 return Handle<JSObject>();
10686 } 10796 }
10687 10797
10688 // Return the context for this scope. For the local context there might not 10798 // Return the context for this scope. For the local context there might not
10689 // be an actual context. 10799 // be an actual context.
10690 Handle<Context> CurrentContext() { 10800 Handle<Context> CurrentContext() {
10691 if (at_local_ && context_->closure() != *function_) { 10801 if (Type() == ScopeTypeGlobal ||
10802 local_scope_chain_.is_empty()) {
10803 return context_;
10804 } else if (local_scope_chain_.last()->HasContext()) {
10805 return context_;
10806 } else {
10692 return Handle<Context>(); 10807 return Handle<Context>();
10693 } 10808 }
10694 return context_;
10695 } 10809 }
10696 10810
10697 #ifdef DEBUG 10811 #ifdef DEBUG
10698 // Debug print of the content of the current scope. 10812 // Debug print of the content of the current scope.
10699 void DebugPrint() { 10813 void DebugPrint() {
10700 switch (Type()) { 10814 switch (Type()) {
10701 case ScopeIterator::ScopeTypeGlobal: 10815 case ScopeIterator::ScopeTypeGlobal:
10702 PrintF("Global:\n"); 10816 PrintF("Global:\n");
10703 CurrentContext()->Print(); 10817 CurrentContext()->Print();
10704 break; 10818 break;
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after
10747 PrintF("\n"); 10861 PrintF("\n");
10748 } 10862 }
10749 #endif 10863 #endif
10750 10864
10751 private: 10865 private:
10752 Isolate* isolate_; 10866 Isolate* isolate_;
10753 JavaScriptFrame* frame_; 10867 JavaScriptFrame* frame_;
10754 int inlined_frame_index_; 10868 int inlined_frame_index_;
10755 Handle<JSFunction> function_; 10869 Handle<JSFunction> function_;
10756 Handle<Context> context_; 10870 Handle<Context> context_;
10757 bool local_done_; 10871 List<Handle<SerializedScopeInfo> > local_scope_chain_;
10758 bool at_local_;
10759 10872
10760 DISALLOW_IMPLICIT_CONSTRUCTORS(ScopeIterator); 10873 DISALLOW_IMPLICIT_CONSTRUCTORS(ScopeIterator);
10761 }; 10874 };
10762 10875
10763 10876
10764 RUNTIME_FUNCTION(MaybeObject*, Runtime_GetScopeCount) { 10877 RUNTIME_FUNCTION(MaybeObject*, Runtime_GetScopeCount) {
10765 HandleScope scope(isolate); 10878 HandleScope scope(isolate);
10766 ASSERT(args.length() == 2); 10879 ASSERT(args.length() == 2);
10767 10880
10768 // Check arguments. 10881 // Check arguments.
(...skipping 1994 matching lines...) Expand 10 before | Expand all | Expand 10 after
12763 } else { 12876 } else {
12764 // Handle last resort GC and make sure to allow future allocations 12877 // Handle last resort GC and make sure to allow future allocations
12765 // to grow the heap without causing GCs (if possible). 12878 // to grow the heap without causing GCs (if possible).
12766 isolate->counters()->gc_last_resort_from_js()->Increment(); 12879 isolate->counters()->gc_last_resort_from_js()->Increment();
12767 isolate->heap()->CollectAllGarbage(false); 12880 isolate->heap()->CollectAllGarbage(false);
12768 } 12881 }
12769 } 12882 }
12770 12883
12771 12884
12772 } } // namespace v8::internal 12885 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « src/rewriter.cc ('k') | src/scopeinfo.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698