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

Side by Side Diff: src/accessors.cc

Issue 6529055: [Isolates] Merge crankshaft (r5922 from bleeding_edge). (Closed)
Patch Set: Win32 port Created 9 years, 10 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
« no previous file with comments | « src/accessors.h ('k') | src/allocation.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 10 matching lines...) Expand all
21 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 21 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
22 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 22 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 23 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 24 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 25 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
26 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 26 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 27
28 #include "v8.h" 28 #include "v8.h"
29 29
30 #include "accessors.h" 30 #include "accessors.h"
31 #include "ast.h"
32 #include "deoptimizer.h"
31 #include "execution.h" 33 #include "execution.h"
32 #include "factory.h" 34 #include "factory.h"
35 #include "safepoint-table.h"
33 #include "scopeinfo.h" 36 #include "scopeinfo.h"
34 37
35 namespace v8 { 38 namespace v8 {
36 namespace internal { 39 namespace internal {
37 40
38 41
39 template <class C> 42 template <class C>
40 static C* FindInPrototypeChain(Object* obj, bool* found_it) { 43 static C* FindInPrototypeChain(Object* obj, bool* found_it) {
41 ASSERT(!*found_it); 44 ASSERT(!*found_it);
42 Heap* heap = HEAP; 45 Heap* heap = HEAP;
(...skipping 454 matching lines...) Expand 10 before | Expand all | Expand 10 after
497 500
498 MaybeObject* Accessors::FunctionGetLength(Object* object, void*) { 501 MaybeObject* Accessors::FunctionGetLength(Object* object, void*) {
499 bool found_it = false; 502 bool found_it = false;
500 JSFunction* function = FindInPrototypeChain<JSFunction>(object, &found_it); 503 JSFunction* function = FindInPrototypeChain<JSFunction>(object, &found_it);
501 if (!found_it) return Smi::FromInt(0); 504 if (!found_it) return Smi::FromInt(0);
502 // Check if already compiled. 505 // Check if already compiled.
503 if (!function->shared()->is_compiled()) { 506 if (!function->shared()->is_compiled()) {
504 // If the function isn't compiled yet, the length is not computed 507 // If the function isn't compiled yet, the length is not computed
505 // correctly yet. Compile it now and return the right length. 508 // correctly yet. Compile it now and return the right length.
506 HandleScope scope; 509 HandleScope scope;
507 Handle<SharedFunctionInfo> shared(function->shared()); 510 Handle<JSFunction> handle(function);
508 if (!CompileLazyShared(shared, KEEP_EXCEPTION)) { 511 if (!CompileLazy(handle, KEEP_EXCEPTION)) return Failure::Exception();
509 return Failure::Exception(); 512 return Smi::FromInt(handle->shared()->length());
510 }
511 return Smi::FromInt(shared->length());
512 } else { 513 } else {
513 return Smi::FromInt(function->shared()->length()); 514 return Smi::FromInt(function->shared()->length());
514 } 515 }
515 } 516 }
516 517
517 518
518 const AccessorDescriptor Accessors::FunctionLength = { 519 const AccessorDescriptor Accessors::FunctionLength = {
519 FunctionGetLength, 520 FunctionGetLength,
520 ReadOnlySetAccessor, 521 ReadOnlySetAccessor,
521 0 522 0
(...skipping 17 matching lines...) Expand all
539 FunctionGetName, 540 FunctionGetName,
540 ReadOnlySetAccessor, 541 ReadOnlySetAccessor,
541 0 542 0
542 }; 543 };
543 544
544 545
545 // 546 //
546 // Accessors::FunctionArguments 547 // Accessors::FunctionArguments
547 // 548 //
548 549
550 static Address SlotAddress(JavaScriptFrame* frame, int slot_index) {
551 if (slot_index >= 0) {
552 const int offset = JavaScriptFrameConstants::kLocal0Offset;
553 return frame->fp() + offset - (slot_index * kPointerSize);
554 } else {
555 const int offset = JavaScriptFrameConstants::kReceiverOffset;
556 return frame->caller_sp() + offset + (slot_index * kPointerSize);
557 }
558 }
559
560
561 // We can't intermix stack decoding and allocations because
562 // deoptimization infrastracture is not GC safe.
563 // Thus we build a temporary structure in malloced space.
564 class SlotRef BASE_EMBEDDED {
565 public:
566 enum SlotRepresentation {
567 UNKNOWN,
568 TAGGED,
569 INT32,
570 DOUBLE,
571 LITERAL
572 };
573
574 SlotRef()
575 : addr_(NULL), representation_(UNKNOWN) { }
576
577 SlotRef(Address addr, SlotRepresentation representation)
578 : addr_(addr), representation_(representation) { }
579
580 explicit SlotRef(Object* literal)
581 : literal_(literal), representation_(LITERAL) { }
582
583 Handle<Object> GetValue() {
584 switch (representation_) {
585 case TAGGED:
586 return Handle<Object>(Memory::Object_at(addr_));
587
588 case INT32: {
589 int value = Memory::int32_at(addr_);
590 if (Smi::IsValid(value)) {
591 return Handle<Object>(Smi::FromInt(value));
592 } else {
593 return Isolate::Current()->factory()->NewNumberFromInt(value);
594 }
595 }
596
597 case DOUBLE: {
598 double value = Memory::double_at(addr_);
599 return Isolate::Current()->factory()->NewNumber(value);
600 }
601
602 case LITERAL:
603 return literal_;
604
605 default:
606 UNREACHABLE();
607 return Handle<Object>::null();
608 }
609 }
610
611 private:
612 Address addr_;
613 Handle<Object> literal_;
614 SlotRepresentation representation_;
615 };
616
617
618 static SlotRef ComputeSlotForNextArgument(TranslationIterator* iterator,
619 DeoptimizationInputData* data,
620 JavaScriptFrame* frame) {
621 Translation::Opcode opcode =
622 static_cast<Translation::Opcode>(iterator->Next());
623
624 switch (opcode) {
625 case Translation::BEGIN:
626 case Translation::FRAME:
627 // Peeled off before getting here.
628 break;
629
630 case Translation::ARGUMENTS_OBJECT:
631 // This can be only emitted for local slots not for argument slots.
632 break;
633
634 case Translation::REGISTER:
635 case Translation::INT32_REGISTER:
636 case Translation::DOUBLE_REGISTER:
637 case Translation::DUPLICATE:
638 // We are at safepoint which corresponds to call. All registers are
639 // saved by caller so there would be no live registers at this
640 // point. Thus these translation commands should not be used.
641 break;
642
643 case Translation::STACK_SLOT: {
644 int slot_index = iterator->Next();
645 Address slot_addr = SlotAddress(frame, slot_index);
646 return SlotRef(slot_addr, SlotRef::TAGGED);
647 }
648
649 case Translation::INT32_STACK_SLOT: {
650 int slot_index = iterator->Next();
651 Address slot_addr = SlotAddress(frame, slot_index);
652 return SlotRef(slot_addr, SlotRef::INT32);
653 }
654
655 case Translation::DOUBLE_STACK_SLOT: {
656 int slot_index = iterator->Next();
657 Address slot_addr = SlotAddress(frame, slot_index);
658 return SlotRef(slot_addr, SlotRef::DOUBLE);
659 }
660
661 case Translation::LITERAL: {
662 int literal_index = iterator->Next();
663 return SlotRef(data->LiteralArray()->get(literal_index));
664 }
665 }
666
667 UNREACHABLE();
668 return SlotRef();
669 }
670
671
672
673
674
675 static void ComputeSlotMappingForArguments(JavaScriptFrame* frame,
676 int inlined_frame_index,
677 Vector<SlotRef>* args_slots) {
678 AssertNoAllocation no_gc;
679
680 int deopt_index = AstNode::kNoNumber;
681
682 DeoptimizationInputData* data =
683 static_cast<OptimizedFrame*>(frame)->GetDeoptimizationData(&deopt_index);
684
685 TranslationIterator it(data->TranslationByteArray(),
686 data->TranslationIndex(deopt_index)->value());
687
688 Translation::Opcode opcode = static_cast<Translation::Opcode>(it.Next());
689 ASSERT(opcode == Translation::BEGIN);
690 int frame_count = it.Next();
691
692 USE(frame_count);
693 ASSERT(frame_count > inlined_frame_index);
694
695 int frames_to_skip = inlined_frame_index;
696 while (true) {
697 opcode = static_cast<Translation::Opcode>(it.Next());
698
699 // Skip over operands to advance to the next opcode.
700 it.Skip(Translation::NumberOfOperandsFor(opcode));
701
702 if (opcode == Translation::FRAME) {
703 if (frames_to_skip == 0) {
704 // We reached frame corresponding to inlined function in question.
705 // Process translation commands for arguments.
706
707 // Skip translation command for receiver.
708 it.Skip(Translation::NumberOfOperandsFor(
709 static_cast<Translation::Opcode>(it.Next())));
710
711 // Compute slots for arguments.
712 for (int i = 0; i < args_slots->length(); ++i) {
713 (*args_slots)[i] = ComputeSlotForNextArgument(&it, data, frame);
714 }
715
716 return;
717 }
718
719 frames_to_skip--;
720 }
721 }
722
723 UNREACHABLE();
724 }
725
726
727 static MaybeObject* ConstructArgumentsObjectForInlinedFunction(
728 JavaScriptFrame* frame,
729 Handle<JSFunction> inlined_function,
730 int inlined_frame_index) {
731 Isolate* isolate = Isolate::Current();
732 Factory* factory = isolate->factory();
733
734 int args_count = inlined_function->shared()->formal_parameter_count();
735
736 ScopedVector<SlotRef> args_slots(args_count);
737
738 ComputeSlotMappingForArguments(frame, inlined_frame_index, &args_slots);
739
740 Handle<JSObject> arguments =
741 factory->NewArgumentsObject(inlined_function, args_count);
742
743 Handle<FixedArray> array = factory->NewFixedArray(args_count);
744 for (int i = 0; i < args_count; ++i) {
745 Handle<Object> value = args_slots[i].GetValue();
746 array->set(i, *value);
747 }
748 arguments->set_elements(*array);
749
750 // Return the freshly allocated arguments object.
751 return *arguments;
752 }
753
549 754
550 MaybeObject* Accessors::FunctionGetArguments(Object* object, void*) { 755 MaybeObject* Accessors::FunctionGetArguments(Object* object, void*) {
551 HandleScope scope; 756 Isolate* isolate = Isolate::Current();
757 HandleScope scope(isolate);
552 bool found_it = false; 758 bool found_it = false;
553 JSFunction* holder = FindInPrototypeChain<JSFunction>(object, &found_it); 759 JSFunction* holder = FindInPrototypeChain<JSFunction>(object, &found_it);
554 if (!found_it) return HEAP->undefined_value(); 760 if (!found_it) return isolate->heap()->undefined_value();
555 Handle<JSFunction> function(holder); 761 Handle<JSFunction> function(holder, isolate);
556 762
557 // Find the top invocation of the function by traversing frames. 763 // Find the top invocation of the function by traversing frames.
764 List<JSFunction*> functions(2);
558 for (JavaScriptFrameIterator it; !it.done(); it.Advance()) { 765 for (JavaScriptFrameIterator it; !it.done(); it.Advance()) {
559 // Skip all frames that aren't invocations of the given function.
560 JavaScriptFrame* frame = it.frame(); 766 JavaScriptFrame* frame = it.frame();
561 if (frame->function() != *function) continue; 767 frame->GetFunctions(&functions);
562 768 for (int i = functions.length() - 1; i >= 0; i--) {
563 // If there is an arguments variable in the stack, we return that. 769 // Skip all frames that aren't invocations of the given function.
564 int index = function->shared()->scope_info()-> 770 if (functions[i] != *function) continue;
565 StackSlotIndex(HEAP->arguments_symbol()); 771
566 if (index >= 0) { 772 if (i > 0) {
567 Handle<Object> arguments = Handle<Object>(frame->GetExpression(index)); 773 // Function in question was inlined.
568 if (!arguments->IsTheHole()) return *arguments; 774 return ConstructArgumentsObjectForInlinedFunction(frame, function, i);
569 } 775 } else {
570 776 // If there is an arguments variable in the stack, we return that.
571 // If there isn't an arguments variable in the stack, we need to 777 int index = function->shared()->scope_info()->
572 // find the frame that holds the actual arguments passed to the 778 StackSlotIndex(isolate->heap()->arguments_symbol());
573 // function on the stack. 779 if (index >= 0) {
574 it.AdvanceToArgumentsFrame(); 780 Handle<Object> arguments =
575 frame = it.frame(); 781 Handle<Object>(frame->GetExpression(index), isolate);
576 782 if (!arguments->IsTheHole()) return *arguments;
577 // Get the number of arguments and construct an arguments object 783 }
578 // mirror for the right frame. 784
579 const int length = frame->GetProvidedParametersCount(); 785 // If there isn't an arguments variable in the stack, we need to
580 Handle<JSObject> arguments = FACTORY->NewArgumentsObject(function, length); 786 // find the frame that holds the actual arguments passed to the
581 Handle<FixedArray> array = FACTORY->NewFixedArray(length); 787 // function on the stack.
582 788 it.AdvanceToArgumentsFrame();
583 // Copy the parameters to the arguments object. 789 frame = it.frame();
584 ASSERT(array->length() == length); 790
585 for (int i = 0; i < length; i++) array->set(i, frame->GetParameter(i)); 791 // Get the number of arguments and construct an arguments object
586 arguments->set_elements(*array); 792 // mirror for the right frame.
587 793 const int length = frame->GetProvidedParametersCount();
588 // Return the freshly allocated arguments object. 794 Handle<JSObject> arguments = isolate->factory()->NewArgumentsObject(
589 return *arguments; 795 function, length);
796 Handle<FixedArray> array = isolate->factory()->NewFixedArray(length);
797
798 // Copy the parameters to the arguments object.
799 ASSERT(array->length() == length);
800 for (int i = 0; i < length; i++) array->set(i, frame->GetParameter(i));
801 arguments->set_elements(*array);
802
803 // Return the freshly allocated arguments object.
804 return *arguments;
805 }
806 }
807 functions.Rewind(0);
590 } 808 }
591 809
592 // No frame corresponding to the given function found. Return null. 810 // No frame corresponding to the given function found. Return null.
593 return HEAP->null_value(); 811 return isolate->heap()->null_value();
594 } 812 }
595 813
596 814
597 const AccessorDescriptor Accessors::FunctionArguments = { 815 const AccessorDescriptor Accessors::FunctionArguments = {
598 FunctionGetArguments, 816 FunctionGetArguments,
599 ReadOnlySetAccessor, 817 ReadOnlySetAccessor,
600 0 818 0
601 }; 819 };
602 820
603 821
604 // 822 //
605 // Accessors::FunctionCaller 823 // Accessors::FunctionCaller
606 // 824 //
607 825
608 826
609 MaybeObject* Accessors::FunctionGetCaller(Object* object, void*) { 827 MaybeObject* Accessors::FunctionGetCaller(Object* object, void*) {
610 HandleScope scope; 828 Isolate* isolate = Isolate::Current();
829 HandleScope scope(isolate);
611 AssertNoAllocation no_alloc; 830 AssertNoAllocation no_alloc;
612 bool found_it = false; 831 bool found_it = false;
613 JSFunction* holder = FindInPrototypeChain<JSFunction>(object, &found_it); 832 JSFunction* holder = FindInPrototypeChain<JSFunction>(object, &found_it);
614 if (!found_it) return HEAP->undefined_value(); 833 if (!found_it) return isolate->heap()->undefined_value();
615 Handle<JSFunction> function(holder); 834 Handle<JSFunction> function(holder, isolate);
616 835
617 // Find the top invocation of the function by traversing frames. 836 List<JSFunction*> functions(2);
618 for (JavaScriptFrameIterator it; !it.done(); it.Advance()) { 837 for (JavaScriptFrameIterator it; !it.done(); it.Advance()) {
619 // Skip all frames that aren't invocations of the given function. 838 JavaScriptFrame* frame = it.frame();
620 if (it.frame()->function() != *function) continue; 839 frame->GetFunctions(&functions);
621 // Once we have found the frame, we need to go to the caller 840 for (int i = functions.length() - 1; i >= 0; i--) {
622 // frame. This may require skipping through a number of top-level 841 if (functions[i] == *function) {
623 // frames, e.g. frames for scripts not functions. 842 // Once we have found the frame, we need to go to the caller
624 while (true) { 843 // frame. This may require skipping through a number of top-level
625 it.Advance(); 844 // frames, e.g. frames for scripts not functions.
626 if (it.done()) return HEAP->null_value(); 845 if (i > 0) {
627 JSFunction* caller = JSFunction::cast(it.frame()->function()); 846 ASSERT(!functions[i - 1]->shared()->is_toplevel());
628 if (!caller->shared()->is_toplevel()) return caller; 847 return functions[i - 1];
848 } else {
849 for (it.Advance(); !it.done(); it.Advance()) {
850 frame = it.frame();
851 functions.Rewind(0);
852 frame->GetFunctions(&functions);
853 if (!functions.last()->shared()->is_toplevel()) {
854 return functions.last();
855 }
856 ASSERT(functions.length() == 1);
857 }
858 if (it.done()) return isolate->heap()->null_value();
859 break;
860 }
861 }
629 } 862 }
863 functions.Rewind(0);
630 } 864 }
631 865
632 // No frame corresponding to the given function found. Return null. 866 // No frame corresponding to the given function found. Return null.
633 return HEAP->null_value(); 867 return isolate->heap()->null_value();
634 } 868 }
635 869
636 870
637 const AccessorDescriptor Accessors::FunctionCaller = { 871 const AccessorDescriptor Accessors::FunctionCaller = {
638 FunctionGetCaller, 872 FunctionGetCaller,
639 ReadOnlySetAccessor, 873 ReadOnlySetAccessor,
640 0 874 0
641 }; 875 };
642 876
643 877
(...skipping 21 matching lines...) Expand all
665 } 899 }
666 900
667 901
668 const AccessorDescriptor Accessors::ObjectPrototype = { 902 const AccessorDescriptor Accessors::ObjectPrototype = {
669 ObjectGetPrototype, 903 ObjectGetPrototype,
670 ObjectSetPrototype, 904 ObjectSetPrototype,
671 0 905 0
672 }; 906 };
673 907
674 } } // namespace v8::internal 908 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « src/accessors.h ('k') | src/allocation.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698