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

Side by Side Diff: src/ic.cc

Issue 106313003: Reland "Allocation site support for monomorphic StringAdds in BinaryOps". (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Created 6 years, 11 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/ic.h ('k') | src/objects.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 2012 the V8 project authors. All rights reserved. 1 // Copyright 2012 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 2579 matching lines...) Expand 10 before | Expand all | Expand 10 after
2590 } 2590 }
2591 ASSERT_NE(GENERIC, result_kind); 2591 ASSERT_NE(GENERIC, result_kind);
2592 return KindToType(result_kind, isolate); 2592 return KindToType(result_kind, isolate);
2593 } 2593 }
2594 2594
2595 2595
2596 void BinaryOpIC::State::Print(StringStream* stream) const { 2596 void BinaryOpIC::State::Print(StringStream* stream) const {
2597 stream->Add("(%s", Token::Name(op_)); 2597 stream->Add("(%s", Token::Name(op_));
2598 if (mode_ == OVERWRITE_LEFT) stream->Add("_ReuseLeft"); 2598 if (mode_ == OVERWRITE_LEFT) stream->Add("_ReuseLeft");
2599 else if (mode_ == OVERWRITE_RIGHT) stream->Add("_ReuseRight"); 2599 else if (mode_ == OVERWRITE_RIGHT) stream->Add("_ReuseRight");
2600 if (CouldCreateAllocationMementos()) stream->Add("_CreateAllocationMementos");
2600 stream->Add(":%s*", KindToString(left_kind_)); 2601 stream->Add(":%s*", KindToString(left_kind_));
2601 if (fixed_right_arg_.has_value) { 2602 if (fixed_right_arg_.has_value) {
2602 stream->Add("%d", fixed_right_arg_.value); 2603 stream->Add("%d", fixed_right_arg_.value);
2603 } else { 2604 } else {
2604 stream->Add("%s", KindToString(right_kind_)); 2605 stream->Add("%s", KindToString(right_kind_));
2605 } 2606 }
2606 stream->Add("->%s)", KindToString(result_kind_)); 2607 stream->Add("->%s)", KindToString(result_kind_));
2607 } 2608 }
2608 2609
2609 2610
(...skipping 19 matching lines...) Expand all
2629 2630
2630 result_kind_ = UpdateKind(result, result_kind_); 2631 result_kind_ = UpdateKind(result, result_kind_);
2631 2632
2632 if (!Token::IsTruncatingBinaryOp(op_)) { 2633 if (!Token::IsTruncatingBinaryOp(op_)) {
2633 Kind input_kind = Max(left_kind_, right_kind_); 2634 Kind input_kind = Max(left_kind_, right_kind_);
2634 if (result_kind_ < input_kind && input_kind <= NUMBER) { 2635 if (result_kind_ < input_kind && input_kind <= NUMBER) {
2635 result_kind_ = input_kind; 2636 result_kind_ = input_kind;
2636 } 2637 }
2637 } 2638 }
2638 2639
2640 // We don't want to distinguish INT32 and NUMBER for string add (because
2641 // NumberToString can't make use of this anyway).
2642 if (left_kind_ == STRING && right_kind_ == INT32) {
2643 ASSERT_EQ(STRING, result_kind_);
2644 ASSERT_EQ(Token::ADD, op_);
2645 right_kind_ = NUMBER;
2646 } else if (right_kind_ == STRING && left_kind_ == INT32) {
2647 ASSERT_EQ(STRING, result_kind_);
2648 ASSERT_EQ(Token::ADD, op_);
2649 left_kind_ = NUMBER;
2650 }
2651
2639 // Reset overwrite mode unless we can actually make use of it, or may be able 2652 // Reset overwrite mode unless we can actually make use of it, or may be able
2640 // to make use of it at some point in the future. 2653 // to make use of it at some point in the future.
2641 if ((mode_ == OVERWRITE_LEFT && left_kind_ > NUMBER) || 2654 if ((mode_ == OVERWRITE_LEFT && left_kind_ > NUMBER) ||
2642 (mode_ == OVERWRITE_RIGHT && right_kind_ > NUMBER) || 2655 (mode_ == OVERWRITE_RIGHT && right_kind_ > NUMBER) ||
2643 result_kind_ > NUMBER) { 2656 result_kind_ > NUMBER) {
2644 mode_ = NO_OVERWRITE; 2657 mode_ = NO_OVERWRITE;
2645 } 2658 }
2646 2659
2647 if (old_extra_ic_state == GetExtraICState()) { 2660 if (old_extra_ic_state == GetExtraICState()) {
2648 // Tagged operations can lead to non-truncating HChanges 2661 // Tagged operations can lead to non-truncating HChanges
(...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after
2714 case SMI: type = Type::Smi(); break; 2727 case SMI: type = Type::Smi(); break;
2715 case INT32: type = Type::Signed32(); break; 2728 case INT32: type = Type::Signed32(); break;
2716 case NUMBER: type = Type::Number(); break; 2729 case NUMBER: type = Type::Number(); break;
2717 case STRING: type = Type::String(); break; 2730 case STRING: type = Type::String(); break;
2718 case GENERIC: type = Type::Any(); break; 2731 case GENERIC: type = Type::Any(); break;
2719 } 2732 }
2720 return handle(type, isolate); 2733 return handle(type, isolate);
2721 } 2734 }
2722 2735
2723 2736
2724 MaybeObject* BinaryOpIC::Transition(Handle<Object> left, Handle<Object> right) { 2737 MaybeObject* BinaryOpIC::Transition(Handle<AllocationSite> allocation_site,
2738 Handle<Object> left,
2739 Handle<Object> right) {
2725 State state(target()->extended_extra_ic_state()); 2740 State state(target()->extended_extra_ic_state());
2726 2741
2727 // Compute the actual result using the builtin for the binary operation. 2742 // Compute the actual result using the builtin for the binary operation.
2728 Object* builtin = isolate()->js_builtins_object()->javascript_builtin( 2743 Object* builtin = isolate()->js_builtins_object()->javascript_builtin(
2729 TokenToJSBuiltin(state.op())); 2744 TokenToJSBuiltin(state.op()));
2730 Handle<JSFunction> function = handle(JSFunction::cast(builtin), isolate()); 2745 Handle<JSFunction> function = handle(JSFunction::cast(builtin), isolate());
2731 bool caught_exception; 2746 bool caught_exception;
2732 Handle<Object> result = Execution::Call( 2747 Handle<Object> result = Execution::Call(
2733 isolate(), function, left, 1, &right, &caught_exception); 2748 isolate(), function, left, 1, &right, &caught_exception);
2734 if (caught_exception) return Failure::Exception(); 2749 if (caught_exception) return Failure::Exception();
2735 2750
2736 // Compute the new state. 2751 // Compute the new state.
2737 State old_state = state; 2752 State old_state = state;
2738 state.Update(left, right, result); 2753 state.Update(left, right, result);
2739 2754
2740 // Install the new stub. 2755 // Check if we have a string operation here.
2741 BinaryOpICStub stub(state); 2756 Handle<Code> target;
2742 set_target(*stub.GetCode(isolate())); 2757 if (!allocation_site.is_null() || state.ShouldCreateAllocationMementos()) {
2758 // Setup the allocation site on-demand.
2759 if (allocation_site.is_null()) {
2760 allocation_site = isolate()->factory()->NewAllocationSite();
2761 }
2762
2763 // Install the stub with an allocation site.
2764 BinaryOpICWithAllocationSiteStub stub(state);
2765 target = stub.GetCodeCopyFromTemplate(isolate(), allocation_site);
2766
2767 // Sanity check the trampoline stub.
2768 ASSERT_EQ(*allocation_site, target->FindFirstAllocationSite());
2769 } else {
2770 // Install the generic stub.
2771 BinaryOpICStub stub(state);
2772 target = stub.GetCode(isolate());
2773
2774 // Sanity check the generic stub.
2775 ASSERT_EQ(NULL, target->FindFirstAllocationSite());
2776 }
2777 set_target(*target);
2743 2778
2744 if (FLAG_trace_ic) { 2779 if (FLAG_trace_ic) {
2745 char buffer[150]; 2780 char buffer[150];
2746 NoAllocationStringAllocator allocator( 2781 NoAllocationStringAllocator allocator(
2747 buffer, static_cast<unsigned>(sizeof(buffer))); 2782 buffer, static_cast<unsigned>(sizeof(buffer)));
2748 StringStream stream(&allocator); 2783 StringStream stream(&allocator);
2749 stream.Add("[BinaryOpIC"); 2784 stream.Add("[BinaryOpIC");
2750 old_state.Print(&stream); 2785 old_state.Print(&stream);
2751 stream.Add(" => "); 2786 stream.Add(" => ");
2752 state.Print(&stream); 2787 state.Print(&stream);
2753 stream.Add(" @ %p <- ", static_cast<void*>(*target())); 2788 stream.Add(" @ %p <- ", static_cast<void*>(*target));
2754 stream.OutputToStdOut(); 2789 stream.OutputToStdOut();
2755 JavaScriptFrame::PrintTop(isolate(), stdout, false, true); 2790 JavaScriptFrame::PrintTop(isolate(), stdout, false, true);
2791 if (!allocation_site.is_null()) {
2792 PrintF(" using allocation site %p", static_cast<void*>(*allocation_site));
2793 }
2756 PrintF("]\n"); 2794 PrintF("]\n");
2757 } 2795 }
2758 2796
2759 // Patch the inlined smi code as necessary. 2797 // Patch the inlined smi code as necessary.
2760 if (!old_state.UseInlinedSmiCode() && state.UseInlinedSmiCode()) { 2798 if (!old_state.UseInlinedSmiCode() && state.UseInlinedSmiCode()) {
2761 PatchInlinedSmiCode(address(), ENABLE_INLINED_SMI_CHECK); 2799 PatchInlinedSmiCode(address(), ENABLE_INLINED_SMI_CHECK);
2762 } else if (old_state.UseInlinedSmiCode() && !state.UseInlinedSmiCode()) { 2800 } else if (old_state.UseInlinedSmiCode() && !state.UseInlinedSmiCode()) {
2763 PatchInlinedSmiCode(address(), DISABLE_INLINED_SMI_CHECK); 2801 PatchInlinedSmiCode(address(), DISABLE_INLINED_SMI_CHECK);
2764 } 2802 }
2765 2803
2766 return *result; 2804 return *result;
2767 } 2805 }
2768 2806
2769 2807
2770 RUNTIME_FUNCTION(MaybeObject*, BinaryOpIC_Miss) { 2808 RUNTIME_FUNCTION(MaybeObject*, BinaryOpIC_Miss) {
2771 HandleScope scope(isolate); 2809 HandleScope scope(isolate);
2810 ASSERT_EQ(2, args.length());
2772 Handle<Object> left = args.at<Object>(BinaryOpICStub::kLeft); 2811 Handle<Object> left = args.at<Object>(BinaryOpICStub::kLeft);
2773 Handle<Object> right = args.at<Object>(BinaryOpICStub::kRight); 2812 Handle<Object> right = args.at<Object>(BinaryOpICStub::kRight);
2774 BinaryOpIC ic(isolate); 2813 BinaryOpIC ic(isolate);
2775 return ic.Transition(left, right); 2814 return ic.Transition(Handle<AllocationSite>::null(), left, right);
2776 } 2815 }
2777 2816
2778 2817
2818 RUNTIME_FUNCTION(MaybeObject*, BinaryOpIC_MissWithAllocationSite) {
2819 HandleScope scope(isolate);
2820 ASSERT_EQ(3, args.length());
2821 Handle<AllocationSite> allocation_site = args.at<AllocationSite>(
2822 BinaryOpWithAllocationSiteStub::kAllocationSite);
2823 Handle<Object> left = args.at<Object>(
2824 BinaryOpWithAllocationSiteStub::kLeft);
2825 Handle<Object> right = args.at<Object>(
2826 BinaryOpWithAllocationSiteStub::kRight);
2827 BinaryOpIC ic(isolate);
2828 return ic.Transition(allocation_site, left, right);
2829 }
2830
2831
2779 Code* CompareIC::GetRawUninitialized(Isolate* isolate, Token::Value op) { 2832 Code* CompareIC::GetRawUninitialized(Isolate* isolate, Token::Value op) {
2780 ICCompareStub stub(op, UNINITIALIZED, UNINITIALIZED, UNINITIALIZED); 2833 ICCompareStub stub(op, UNINITIALIZED, UNINITIALIZED, UNINITIALIZED);
2781 Code* code = NULL; 2834 Code* code = NULL;
2782 CHECK(stub.FindCodeInCache(&code, isolate)); 2835 CHECK(stub.FindCodeInCache(&code, isolate));
2783 return code; 2836 return code;
2784 } 2837 }
2785 2838
2786 2839
2787 Handle<Code> CompareIC::GetUninitialized(Isolate* isolate, Token::Value op) { 2840 Handle<Code> CompareIC::GetUninitialized(Isolate* isolate, Token::Value op) {
2788 ICCompareStub stub(op, UNINITIALIZED, UNINITIALIZED, UNINITIALIZED); 2841 ICCompareStub stub(op, UNINITIALIZED, UNINITIALIZED, UNINITIALIZED);
(...skipping 350 matching lines...) Expand 10 before | Expand all | Expand 10 after
3139 #undef ADDR 3192 #undef ADDR
3140 }; 3193 };
3141 3194
3142 3195
3143 Address IC::AddressFromUtilityId(IC::UtilityId id) { 3196 Address IC::AddressFromUtilityId(IC::UtilityId id) {
3144 return IC_utilities[id]; 3197 return IC_utilities[id];
3145 } 3198 }
3146 3199
3147 3200
3148 } } // namespace v8::internal 3201 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « src/ic.h ('k') | src/objects.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698