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

Side by Side Diff: src/ic.cc

Issue 157503002: A64: Synchronize with r18444. (Closed) Base URL: https://v8.googlecode.com/svn/branches/experimental/a64
Patch Set: Created 6 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 | Annotate | Revision Log
« no previous file with comments | « src/ic.h ('k') | src/isolate.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 17 matching lines...) Expand all
28 #include "v8.h" 28 #include "v8.h"
29 29
30 #include "accessors.h" 30 #include "accessors.h"
31 #include "api.h" 31 #include "api.h"
32 #include "arguments.h" 32 #include "arguments.h"
33 #include "codegen.h" 33 #include "codegen.h"
34 #include "execution.h" 34 #include "execution.h"
35 #include "ic-inl.h" 35 #include "ic-inl.h"
36 #include "runtime.h" 36 #include "runtime.h"
37 #include "stub-cache.h" 37 #include "stub-cache.h"
38 #include "v8conversions.h"
38 39
39 namespace v8 { 40 namespace v8 {
40 namespace internal { 41 namespace internal {
41 42
42 #ifdef DEBUG 43 #ifdef DEBUG
43 char IC::TransitionMarkFromState(IC::State state) { 44 char IC::TransitionMarkFromState(IC::State state) {
44 switch (state) { 45 switch (state) {
45 case UNINITIALIZED: return '0'; 46 case UNINITIALIZED: return '0';
46 case PREMONOMORPHIC: return '.'; 47 case PREMONOMORPHIC: return '.';
47 case MONOMORPHIC: return '1'; 48 case MONOMORPHIC: return '1';
(...skipping 385 matching lines...) Expand 10 before | Expand all | Expand 10 after
433 bool was_uninitialized = 434 bool was_uninitialized =
434 old_state == UNINITIALIZED || old_state == PREMONOMORPHIC; 435 old_state == UNINITIALIZED || old_state == PREMONOMORPHIC;
435 bool is_uninitialized = 436 bool is_uninitialized =
436 new_state == UNINITIALIZED || new_state == PREMONOMORPHIC; 437 new_state == UNINITIALIZED || new_state == PREMONOMORPHIC;
437 return (was_uninitialized && !is_uninitialized) ? 1 : 438 return (was_uninitialized && !is_uninitialized) ? 1 :
438 (!was_uninitialized && is_uninitialized) ? -1 : 0; 439 (!was_uninitialized && is_uninitialized) ? -1 : 0;
439 } 440 }
440 441
441 442
442 void IC::PostPatching(Address address, Code* target, Code* old_target) { 443 void IC::PostPatching(Address address, Code* target, Code* old_target) {
443 if (FLAG_type_info_threshold == 0 && !FLAG_watch_ic_patching) {
444 return;
445 }
446 Isolate* isolate = target->GetHeap()->isolate(); 444 Isolate* isolate = target->GetHeap()->isolate();
447 Code* host = isolate-> 445 Code* host = isolate->
448 inner_pointer_to_code_cache()->GetCacheEntry(address)->code; 446 inner_pointer_to_code_cache()->GetCacheEntry(address)->code;
449 if (host->kind() != Code::FUNCTION) return; 447 if (host->kind() != Code::FUNCTION) return;
450 448
451 if (FLAG_type_info_threshold > 0 && 449 if (FLAG_type_info_threshold > 0 &&
452 old_target->is_inline_cache_stub() && 450 old_target->is_inline_cache_stub() &&
453 target->is_inline_cache_stub()) { 451 target->is_inline_cache_stub()) {
454 int delta = ComputeTypeInfoCountDelta(old_target->ic_state(), 452 int delta = ComputeTypeInfoCountDelta(old_target->ic_state(),
455 target->ic_state()); 453 target->ic_state());
456 // Not all Code objects have TypeFeedbackInfo. 454 // Not all Code objects have TypeFeedbackInfo.
457 if (host->type_feedback_info()->IsTypeFeedbackInfo() && delta != 0) { 455 if (host->type_feedback_info()->IsTypeFeedbackInfo() && delta != 0) {
458 TypeFeedbackInfo* info = 456 TypeFeedbackInfo* info =
459 TypeFeedbackInfo::cast(host->type_feedback_info()); 457 TypeFeedbackInfo::cast(host->type_feedback_info());
460 info->change_ic_with_type_info_count(delta); 458 info->change_ic_with_type_info_count(delta);
461 } 459 }
462 } 460 }
463 if (host->type_feedback_info()->IsTypeFeedbackInfo()) { 461 if (host->type_feedback_info()->IsTypeFeedbackInfo()) {
464 TypeFeedbackInfo* info = 462 TypeFeedbackInfo* info =
465 TypeFeedbackInfo::cast(host->type_feedback_info()); 463 TypeFeedbackInfo::cast(host->type_feedback_info());
466 info->change_own_type_change_checksum(); 464 info->change_own_type_change_checksum();
467 } 465 }
468 if (FLAG_watch_ic_patching) { 466 host->set_profiler_ticks(0);
469 host->set_profiler_ticks(0); 467 isolate->runtime_profiler()->NotifyICChanged();
470 isolate->runtime_profiler()->NotifyICChanged();
471 }
472 // TODO(2029): When an optimized function is patched, it would 468 // TODO(2029): When an optimized function is patched, it would
473 // be nice to propagate the corresponding type information to its 469 // be nice to propagate the corresponding type information to its
474 // unoptimized version for the benefit of later inlining. 470 // unoptimized version for the benefit of later inlining.
475 } 471 }
476 472
477 473
478 void IC::Clear(Isolate* isolate, Address address) { 474 void IC::Clear(Isolate* isolate, Address address) {
479 Code* target = GetTargetAtAddress(address); 475 Code* target = GetTargetAtAddress(address);
480 476
481 // Don't clear debug break inline cache as it will remove the break point. 477 // Don't clear debug break inline cache as it will remove the break point.
(...skipping 1569 matching lines...) Expand 10 before | Expand all | Expand 10 after
2051 if (!maybe_result->To(&raw_function)) return maybe_result; 2047 if (!maybe_result->To(&raw_function)) return maybe_result;
2052 2048
2053 // The first time the inline cache is updated may be the first time the 2049 // The first time the inline cache is updated may be the first time the
2054 // function it references gets called. If the function is lazily compiled 2050 // function it references gets called. If the function is lazily compiled
2055 // then the first call will trigger a compilation. We check for this case 2051 // then the first call will trigger a compilation. We check for this case
2056 // and we do the compilation immediately, instead of waiting for the stub 2052 // and we do the compilation immediately, instead of waiting for the stub
2057 // currently attached to the JSFunction object to trigger compilation. 2053 // currently attached to the JSFunction object to trigger compilation.
2058 if (raw_function->is_compiled()) return raw_function; 2054 if (raw_function->is_compiled()) return raw_function;
2059 2055
2060 Handle<JSFunction> function(raw_function); 2056 Handle<JSFunction> function(raw_function);
2061 JSFunction::CompileLazy(function, CLEAR_EXCEPTION); 2057 Compiler::EnsureCompiled(function, CLEAR_EXCEPTION);
2062 return *function; 2058 return *function;
2063 } 2059 }
2064 2060
2065 2061
2066 // Used from ic-<arch>.cc. 2062 // Used from ic-<arch>.cc.
2067 RUNTIME_FUNCTION(MaybeObject*, KeyedCallIC_Miss) { 2063 RUNTIME_FUNCTION(MaybeObject*, KeyedCallIC_Miss) {
2068 HandleScope scope(isolate); 2064 HandleScope scope(isolate);
2069 ASSERT(args.length() == 2); 2065 ASSERT(args.length() == 2);
2070 KeyedCallIC ic(isolate); 2066 KeyedCallIC ic(isolate);
2071 Handle<Object> receiver = args.at<Object>(0); 2067 Handle<Object> receiver = args.at<Object>(0);
2072 Handle<Object> key = args.at<Object>(1); 2068 Handle<Object> key = args.at<Object>(1);
2073 ic.UpdateState(receiver, key); 2069 ic.UpdateState(receiver, key);
2074 MaybeObject* maybe_result = ic.LoadFunction(receiver, key); 2070 MaybeObject* maybe_result = ic.LoadFunction(receiver, key);
2075 // Result could be a function or a failure. 2071 // Result could be a function or a failure.
2076 JSFunction* raw_function = NULL; 2072 JSFunction* raw_function = NULL;
2077 if (!maybe_result->To(&raw_function)) return maybe_result; 2073 if (!maybe_result->To(&raw_function)) return maybe_result;
2078 2074
2079 if (raw_function->is_compiled()) return raw_function; 2075 if (raw_function->is_compiled()) return raw_function;
2080 2076
2081 Handle<JSFunction> function(raw_function, isolate); 2077 Handle<JSFunction> function(raw_function, isolate);
2082 JSFunction::CompileLazy(function, CLEAR_EXCEPTION); 2078 Compiler::EnsureCompiled(function, CLEAR_EXCEPTION);
2083 return *function; 2079 return *function;
2084 } 2080 }
2085 2081
2086 2082
2087 // Used from ic-<arch>.cc. 2083 // Used from ic-<arch>.cc.
2088 RUNTIME_FUNCTION(MaybeObject*, LoadIC_Miss) { 2084 RUNTIME_FUNCTION(MaybeObject*, LoadIC_Miss) {
2089 HandleScope scope(isolate); 2085 HandleScope scope(isolate);
2090 ASSERT(args.length() == 2); 2086 ASSERT(args.length() == 2);
2091 LoadIC ic(IC::NO_EXTRA_FRAME, isolate); 2087 LoadIC ic(IC::NO_EXTRA_FRAME, isolate);
2092 Handle<Object> receiver = args.at<Object>(0); 2088 Handle<Object> receiver = args.at<Object>(0);
(...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after
2152 2148
2153 ic.UpdateState(receiver, key); 2149 ic.UpdateState(receiver, key);
2154 MaybeObject* maybe_result = ic.LoadFunction(receiver, key); 2150 MaybeObject* maybe_result = ic.LoadFunction(receiver, key);
2155 // Result could be a function or a failure. 2151 // Result could be a function or a failure.
2156 JSFunction* raw_function = NULL; 2152 JSFunction* raw_function = NULL;
2157 if (!maybe_result->To(&raw_function)) return maybe_result; 2153 if (!maybe_result->To(&raw_function)) return maybe_result;
2158 2154
2159 if (raw_function->is_compiled()) return raw_function; 2155 if (raw_function->is_compiled()) return raw_function;
2160 2156
2161 Handle<JSFunction> function(raw_function, isolate); 2157 Handle<JSFunction> function(raw_function, isolate);
2162 JSFunction::CompileLazy(function, CLEAR_EXCEPTION); 2158 Compiler::EnsureCompiled(function, CLEAR_EXCEPTION);
2163 return *function; 2159 return *function;
2164 } 2160 }
2165 2161
2166 2162
2167 RUNTIME_FUNCTION(MaybeObject*, StoreIC_ArrayLength) { 2163 RUNTIME_FUNCTION(MaybeObject*, StoreIC_ArrayLength) {
2168 SealHandleScope shs(isolate); 2164 SealHandleScope shs(isolate);
2169 2165
2170 ASSERT(args.length() == 2); 2166 ASSERT(args.length() == 2);
2171 JSArray* receiver = JSArray::cast(args[0]); 2167 JSArray* receiver = JSArray::cast(args[0]);
2172 Object* len = args[1]; 2168 Object* len = args[1];
(...skipping 421 matching lines...) Expand 10 before | Expand all | Expand 10 after
2594 } 2590 }
2595 ASSERT_NE(GENERIC, result_kind); 2591 ASSERT_NE(GENERIC, result_kind);
2596 return KindToType(result_kind, isolate); 2592 return KindToType(result_kind, isolate);
2597 } 2593 }
2598 2594
2599 2595
2600 void BinaryOpIC::State::Print(StringStream* stream) const { 2596 void BinaryOpIC::State::Print(StringStream* stream) const {
2601 stream->Add("(%s", Token::Name(op_)); 2597 stream->Add("(%s", Token::Name(op_));
2602 if (mode_ == OVERWRITE_LEFT) stream->Add("_ReuseLeft"); 2598 if (mode_ == OVERWRITE_LEFT) stream->Add("_ReuseLeft");
2603 else if (mode_ == OVERWRITE_RIGHT) stream->Add("_ReuseRight"); 2599 else if (mode_ == OVERWRITE_RIGHT) stream->Add("_ReuseRight");
2600 if (CouldCreateAllocationMementos()) stream->Add("_CreateAllocationMementos");
2604 stream->Add(":%s*", KindToString(left_kind_)); 2601 stream->Add(":%s*", KindToString(left_kind_));
2605 if (fixed_right_arg_.has_value) { 2602 if (fixed_right_arg_.has_value) {
2606 stream->Add("%d", fixed_right_arg_.value); 2603 stream->Add("%d", fixed_right_arg_.value);
2607 } else { 2604 } else {
2608 stream->Add("%s", KindToString(right_kind_)); 2605 stream->Add("%s", KindToString(right_kind_));
2609 } 2606 }
2610 stream->Add("->%s)", KindToString(result_kind_)); 2607 stream->Add("->%s)", KindToString(result_kind_));
2611 } 2608 }
2612 2609
2613 2610
(...skipping 19 matching lines...) Expand all
2633 2630
2634 result_kind_ = UpdateKind(result, result_kind_); 2631 result_kind_ = UpdateKind(result, result_kind_);
2635 2632
2636 if (!Token::IsTruncatingBinaryOp(op_)) { 2633 if (!Token::IsTruncatingBinaryOp(op_)) {
2637 Kind input_kind = Max(left_kind_, right_kind_); 2634 Kind input_kind = Max(left_kind_, right_kind_);
2638 if (result_kind_ < input_kind && input_kind <= NUMBER) { 2635 if (result_kind_ < input_kind && input_kind <= NUMBER) {
2639 result_kind_ = input_kind; 2636 result_kind_ = input_kind;
2640 } 2637 }
2641 } 2638 }
2642 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
2643 // 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
2644 // to make use of it at some point in the future. 2653 // to make use of it at some point in the future.
2645 if ((mode_ == OVERWRITE_LEFT && left_kind_ > NUMBER) || 2654 if ((mode_ == OVERWRITE_LEFT && left_kind_ > NUMBER) ||
2646 (mode_ == OVERWRITE_RIGHT && right_kind_ > NUMBER) || 2655 (mode_ == OVERWRITE_RIGHT && right_kind_ > NUMBER) ||
2647 result_kind_ > NUMBER) { 2656 result_kind_ > NUMBER) {
2648 mode_ = NO_OVERWRITE; 2657 mode_ = NO_OVERWRITE;
2649 } 2658 }
2650 2659
2651 if (old_extra_ic_state == GetExtraICState()) { 2660 if (old_extra_ic_state == GetExtraICState()) {
2652 // Tagged operations can lead to non-truncating HChanges 2661 // Tagged operations can lead to non-truncating HChanges
(...skipping 19 matching lines...) Expand all
2672 if (object->IsBoolean() && is_truncating) { 2681 if (object->IsBoolean() && is_truncating) {
2673 // Booleans will be automatically truncated by HChange. 2682 // Booleans will be automatically truncated by HChange.
2674 new_kind = INT32; 2683 new_kind = INT32;
2675 } else if (object->IsUndefined()) { 2684 } else if (object->IsUndefined()) {
2676 // Undefined will be automatically truncated by HChange. 2685 // Undefined will be automatically truncated by HChange.
2677 new_kind = is_truncating ? INT32 : NUMBER; 2686 new_kind = is_truncating ? INT32 : NUMBER;
2678 } else if (object->IsSmi()) { 2687 } else if (object->IsSmi()) {
2679 new_kind = SMI; 2688 new_kind = SMI;
2680 } else if (object->IsHeapNumber()) { 2689 } else if (object->IsHeapNumber()) {
2681 double value = Handle<HeapNumber>::cast(object)->value(); 2690 double value = Handle<HeapNumber>::cast(object)->value();
2682 new_kind = TypeInfo::IsInt32Double(value) ? INT32 : NUMBER; 2691 new_kind = IsInt32Double(value) ? INT32 : NUMBER;
2683 } else if (object->IsString() && op() == Token::ADD) { 2692 } else if (object->IsString() && op() == Token::ADD) {
2684 new_kind = STRING; 2693 new_kind = STRING;
2685 } 2694 }
2686 if (new_kind == INT32 && SmiValuesAre32Bits()) { 2695 if (new_kind == INT32 && SmiValuesAre32Bits()) {
2687 new_kind = NUMBER; 2696 new_kind = NUMBER;
2688 } 2697 }
2689 if (kind != NONE && 2698 if (kind != NONE &&
2690 ((new_kind <= NUMBER && kind > NUMBER) || 2699 ((new_kind <= NUMBER && kind > NUMBER) ||
2691 (new_kind > NUMBER && kind <= NUMBER))) { 2700 (new_kind > NUMBER && kind <= NUMBER))) {
2692 new_kind = GENERIC; 2701 new_kind = GENERIC;
(...skipping 25 matching lines...) Expand all
2718 case SMI: type = Type::Smi(); break; 2727 case SMI: type = Type::Smi(); break;
2719 case INT32: type = Type::Signed32(); break; 2728 case INT32: type = Type::Signed32(); break;
2720 case NUMBER: type = Type::Number(); break; 2729 case NUMBER: type = Type::Number(); break;
2721 case STRING: type = Type::String(); break; 2730 case STRING: type = Type::String(); break;
2722 case GENERIC: type = Type::Any(); break; 2731 case GENERIC: type = Type::Any(); break;
2723 } 2732 }
2724 return handle(type, isolate); 2733 return handle(type, isolate);
2725 } 2734 }
2726 2735
2727 2736
2728 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) {
2729 State state(target()->extended_extra_ic_state()); 2740 State state(target()->extended_extra_ic_state());
2730 2741
2731 // Compute the actual result using the builtin for the binary operation. 2742 // Compute the actual result using the builtin for the binary operation.
2732 Object* builtin = isolate()->js_builtins_object()->javascript_builtin( 2743 Object* builtin = isolate()->js_builtins_object()->javascript_builtin(
2733 TokenToJSBuiltin(state.op())); 2744 TokenToJSBuiltin(state.op()));
2734 Handle<JSFunction> function = handle(JSFunction::cast(builtin), isolate()); 2745 Handle<JSFunction> function = handle(JSFunction::cast(builtin), isolate());
2735 bool caught_exception; 2746 bool caught_exception;
2736 Handle<Object> result = Execution::Call( 2747 Handle<Object> result = Execution::Call(
2737 isolate(), function, left, 1, &right, &caught_exception); 2748 isolate(), function, left, 1, &right, &caught_exception);
2738 if (caught_exception) return Failure::Exception(); 2749 if (caught_exception) return Failure::Exception();
2739 2750
2740 // Compute the new state. 2751 // Compute the new state.
2741 State old_state = state; 2752 State old_state = state;
2742 state.Update(left, right, result); 2753 state.Update(left, right, result);
2743 2754
2744 // Install the new stub. 2755 // Check if we have a string operation here.
2745 BinaryOpICStub stub(state); 2756 Handle<Code> target;
2746 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);
2747 2778
2748 if (FLAG_trace_ic) { 2779 if (FLAG_trace_ic) {
2749 char buffer[150]; 2780 char buffer[150];
2750 NoAllocationStringAllocator allocator( 2781 NoAllocationStringAllocator allocator(
2751 buffer, static_cast<unsigned>(sizeof(buffer))); 2782 buffer, static_cast<unsigned>(sizeof(buffer)));
2752 StringStream stream(&allocator); 2783 StringStream stream(&allocator);
2753 stream.Add("[BinaryOpIC"); 2784 stream.Add("[BinaryOpIC");
2754 old_state.Print(&stream); 2785 old_state.Print(&stream);
2755 stream.Add(" => "); 2786 stream.Add(" => ");
2756 state.Print(&stream); 2787 state.Print(&stream);
2757 stream.Add(" @ %p <- ", static_cast<void*>(*target())); 2788 stream.Add(" @ %p <- ", static_cast<void*>(*target));
2758 stream.OutputToStdOut(); 2789 stream.OutputToStdOut();
2759 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 }
2760 PrintF("]\n"); 2794 PrintF("]\n");
2761 } 2795 }
2762 2796
2763 // Patch the inlined smi code as necessary. 2797 // Patch the inlined smi code as necessary.
2764 if (!old_state.UseInlinedSmiCode() && state.UseInlinedSmiCode()) { 2798 if (!old_state.UseInlinedSmiCode() && state.UseInlinedSmiCode()) {
2765 PatchInlinedSmiCode(address(), ENABLE_INLINED_SMI_CHECK); 2799 PatchInlinedSmiCode(address(), ENABLE_INLINED_SMI_CHECK);
2766 } else if (old_state.UseInlinedSmiCode() && !state.UseInlinedSmiCode()) { 2800 } else if (old_state.UseInlinedSmiCode() && !state.UseInlinedSmiCode()) {
2767 PatchInlinedSmiCode(address(), DISABLE_INLINED_SMI_CHECK); 2801 PatchInlinedSmiCode(address(), DISABLE_INLINED_SMI_CHECK);
2768 } 2802 }
2769 2803
2770 return *result; 2804 return *result;
2771 } 2805 }
2772 2806
2773 2807
2774 RUNTIME_FUNCTION(MaybeObject*, BinaryOpIC_Miss) { 2808 RUNTIME_FUNCTION(MaybeObject*, BinaryOpIC_Miss) {
2775 HandleScope scope(isolate); 2809 HandleScope scope(isolate);
2810 ASSERT_EQ(2, args.length());
2776 Handle<Object> left = args.at<Object>(BinaryOpICStub::kLeft); 2811 Handle<Object> left = args.at<Object>(BinaryOpICStub::kLeft);
2777 Handle<Object> right = args.at<Object>(BinaryOpICStub::kRight); 2812 Handle<Object> right = args.at<Object>(BinaryOpICStub::kRight);
2778 BinaryOpIC ic(isolate); 2813 BinaryOpIC ic(isolate);
2779 return ic.Transition(left, right); 2814 return ic.Transition(Handle<AllocationSite>::null(), left, right);
2780 } 2815 }
2781 2816
2782 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
2783 Code* CompareIC::GetRawUninitialized(Isolate* isolate, Token::Value op) { 2832 Code* CompareIC::GetRawUninitialized(Isolate* isolate, Token::Value op) {
2784 ICCompareStub stub(op, UNINITIALIZED, UNINITIALIZED, UNINITIALIZED); 2833 ICCompareStub stub(op, UNINITIALIZED, UNINITIALIZED, UNINITIALIZED);
2785 Code* code = NULL; 2834 Code* code = NULL;
2786 CHECK(stub.FindCodeInCache(&code, isolate)); 2835 CHECK(stub.FindCodeInCache(&code, isolate));
2787 return code; 2836 return code;
2788 } 2837 }
2789 2838
2790 2839
2791 Handle<Code> CompareIC::GetUninitialized(Isolate* isolate, Token::Value op) { 2840 Handle<Code> CompareIC::GetUninitialized(Isolate* isolate, Token::Value op) {
2792 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
3143 #undef ADDR 3192 #undef ADDR
3144 }; 3193 };
3145 3194
3146 3195
3147 Address IC::AddressFromUtilityId(IC::UtilityId id) { 3196 Address IC::AddressFromUtilityId(IC::UtilityId id) {
3148 return IC_utilities[id]; 3197 return IC_utilities[id];
3149 } 3198 }
3150 3199
3151 3200
3152 } } // namespace v8::internal 3201 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « src/ic.h ('k') | src/isolate.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698