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

Side by Side Diff: src/ast.cc

Issue 148223002: Remove CallICs (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Update test262 status file 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/ast.h ('k') | src/code-stubs.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 120 matching lines...) Expand 10 before | Expand all | Expand 10 after
131 Expression* target, 131 Expression* target,
132 Expression* value, 132 Expression* value,
133 int pos) 133 int pos)
134 : Expression(zone, pos), 134 : Expression(zone, pos),
135 op_(op), 135 op_(op),
136 target_(target), 136 target_(target),
137 value_(value), 137 value_(value),
138 binary_operation_(NULL), 138 binary_operation_(NULL),
139 assignment_id_(GetNextId(zone)), 139 assignment_id_(GetNextId(zone)),
140 is_uninitialized_(false), 140 is_uninitialized_(false),
141 is_pre_monomorphic_(false),
142 store_mode_(STANDARD_STORE) { } 141 store_mode_(STANDARD_STORE) { }
143 142
144 143
145 Token::Value Assignment::binary_op() const { 144 Token::Value Assignment::binary_op() const {
146 switch (op_) { 145 switch (op_) {
147 case Token::ASSIGN_BIT_OR: return Token::BIT_OR; 146 case Token::ASSIGN_BIT_OR: return Token::BIT_OR;
148 case Token::ASSIGN_BIT_XOR: return Token::BIT_XOR; 147 case Token::ASSIGN_BIT_XOR: return Token::BIT_XOR;
149 case Token::ASSIGN_BIT_AND: return Token::BIT_AND; 148 case Token::ASSIGN_BIT_AND: return Token::BIT_AND;
150 case Token::ASSIGN_SHL: return Token::SHL; 149 case Token::ASSIGN_SHL: return Token::SHL;
151 case Token::ASSIGN_SAR: return Token::SAR; 150 case Token::ASSIGN_SAR: return Token::SAR;
(...skipping 452 matching lines...) Expand 10 before | Expand all | Expand 10 after
604 } else if (proxy->var()->IsLookupSlot()) { 603 } else if (proxy->var()->IsLookupSlot()) {
605 return LOOKUP_SLOT_CALL; 604 return LOOKUP_SLOT_CALL;
606 } 605 }
607 } 606 }
608 607
609 Property* property = expression()->AsProperty(); 608 Property* property = expression()->AsProperty();
610 return property != NULL ? PROPERTY_CALL : OTHER_CALL; 609 return property != NULL ? PROPERTY_CALL : OTHER_CALL;
611 } 610 }
612 611
613 612
614 bool Call::ComputeTarget(Handle<Map> type, Handle<String> name) {
615 // If there is an interceptor, we can't compute the target for a direct call.
616 if (type->has_named_interceptor()) return false;
617
618 if (check_type_ == RECEIVER_MAP_CHECK) {
619 // For primitive checks the holder is set up to point to the corresponding
620 // prototype object, i.e. one step of the algorithm below has been already
621 // performed. For non-primitive checks we clear it to allow computing
622 // targets for polymorphic calls.
623 holder_ = Handle<JSObject>::null();
624 }
625 LookupResult lookup(type->GetIsolate());
626 while (true) {
627 // If a dictionary map is found in the prototype chain before the actual
628 // target, a new target can always appear. In that case, bail out.
629 // TODO(verwaest): Alternatively a runtime negative lookup on the normal
630 // receiver or prototype could be added.
631 if (type->is_dictionary_map()) return false;
632 type->LookupDescriptor(NULL, *name, &lookup);
633 if (lookup.IsFound()) {
634 switch (lookup.type()) {
635 case CONSTANT: {
636 // We surely know the target for a constant function.
637 Handle<Object> constant(lookup.GetConstantFromMap(*type),
638 type->GetIsolate());
639 if (constant->IsJSFunction()) {
640 target_ = Handle<JSFunction>::cast(constant);
641 return true;
642 }
643 // Fall through.
644 }
645 case NORMAL:
646 case FIELD:
647 case CALLBACKS:
648 case HANDLER:
649 case INTERCEPTOR:
650 // We don't know the target.
651 return false;
652 case TRANSITION:
653 case NONEXISTENT:
654 UNREACHABLE();
655 break;
656 }
657 }
658 // If we reach the end of the prototype chain, we don't know the target.
659 if (!type->prototype()->IsJSObject()) return false;
660 // Go up the prototype chain, recording where we are currently.
661 holder_ = Handle<JSObject>(JSObject::cast(type->prototype()));
662 type = Handle<Map>(holder()->map());
663 }
664 }
665
666
667 bool Call::ComputeGlobalTarget(Handle<GlobalObject> global, 613 bool Call::ComputeGlobalTarget(Handle<GlobalObject> global,
668 LookupResult* lookup) { 614 LookupResult* lookup) {
669 target_ = Handle<JSFunction>::null(); 615 target_ = Handle<JSFunction>::null();
670 cell_ = Handle<Cell>::null(); 616 cell_ = Handle<Cell>::null();
671 ASSERT(lookup->IsFound() && 617 ASSERT(lookup->IsFound() &&
672 lookup->type() == NORMAL && 618 lookup->type() == NORMAL &&
673 lookup->holder() == *global); 619 lookup->holder() == *global);
674 cell_ = Handle<Cell>(global->GetPropertyCell(lookup)); 620 cell_ = Handle<Cell>(global->GetPropertyCell(lookup));
675 if (cell_->value()->IsJSFunction()) { 621 if (cell_->value()->IsJSFunction()) {
676 Handle<JSFunction> candidate(JSFunction::cast(cell_->value())); 622 Handle<JSFunction> candidate(JSFunction::cast(cell_->value()));
677 // If the function is in new space we assume it's more likely to 623 // If the function is in new space we assume it's more likely to
678 // change and thus prefer the general IC code. 624 // change and thus prefer the general IC code.
679 if (!lookup->isolate()->heap()->InNewSpace(*candidate)) { 625 if (!lookup->isolate()->heap()->InNewSpace(*candidate)) {
680 target_ = candidate; 626 target_ = candidate;
681 return true; 627 return true;
682 } 628 }
683 } 629 }
684 return false; 630 return false;
685 } 631 }
686 632
687 633
688 Handle<JSObject> Call::GetPrototypeForPrimitiveCheck(
689 CheckType check, Isolate* isolate) {
690 v8::internal::Context* native_context = isolate->context()->native_context();
691 JSFunction* function = NULL;
692 switch (check) {
693 case RECEIVER_MAP_CHECK:
694 UNREACHABLE();
695 break;
696 case STRING_CHECK:
697 function = native_context->string_function();
698 break;
699 case SYMBOL_CHECK:
700 function = native_context->symbol_function();
701 break;
702 case NUMBER_CHECK:
703 function = native_context->number_function();
704 break;
705 case BOOLEAN_CHECK:
706 function = native_context->boolean_function();
707 break;
708 }
709 ASSERT(function != NULL);
710 return Handle<JSObject>(JSObject::cast(function->instance_prototype()));
711 }
712
713
714 void Call::RecordTypeFeedback(TypeFeedbackOracle* oracle) {
715 is_monomorphic_ = oracle->CallIsMonomorphic(CallFeedbackId());
716 Property* property = expression()->AsProperty();
717 if (property == NULL) {
718 // Function call. Specialize for monomorphic calls.
719 if (is_monomorphic_) target_ = oracle->GetCallTarget(CallFeedbackId());
720 } else if (property->key()->IsPropertyName()) {
721 // Method call. Specialize for the receiver types seen at runtime.
722 Literal* key = property->key()->AsLiteral();
723 ASSERT(key != NULL && key->value()->IsString());
724 Handle<String> name = Handle<String>::cast(key->value());
725 check_type_ = oracle->GetCallCheckType(CallFeedbackId());
726 receiver_types_.Clear();
727 if (check_type_ == RECEIVER_MAP_CHECK) {
728 oracle->CallReceiverTypes(CallFeedbackId(),
729 name, arguments()->length(), &receiver_types_);
730 is_monomorphic_ = is_monomorphic_ && receiver_types_.length() > 0;
731 } else {
732 holder_ = GetPrototypeForPrimitiveCheck(check_type_, oracle->isolate());
733 receiver_types_.Add(handle(holder_->map()), oracle->zone());
734 }
735 #ifdef ENABLE_SLOW_ASSERTS
736 if (FLAG_enable_slow_asserts) {
737 int length = receiver_types_.length();
738 for (int i = 0; i < length; i++) {
739 Handle<Map> map = receiver_types_.at(i);
740 ASSERT(!map.is_null() && *map != NULL);
741 }
742 }
743 #endif
744 if (is_monomorphic_) {
745 Handle<Map> map = receiver_types_.first();
746 is_monomorphic_ = ComputeTarget(map, name);
747 }
748 } else {
749 if (is_monomorphic_) {
750 keyed_array_call_is_holey_ =
751 oracle->KeyedArrayCallIsHoley(CallFeedbackId());
752 }
753 }
754 }
755
756
757 void CallNew::RecordTypeFeedback(TypeFeedbackOracle* oracle) { 634 void CallNew::RecordTypeFeedback(TypeFeedbackOracle* oracle) {
758 allocation_site_ = 635 allocation_site_ =
759 oracle->GetCallNewAllocationSite(CallNewFeedbackId()); 636 oracle->GetCallNewAllocationSite(CallNewFeedbackId());
760 is_monomorphic_ = oracle->CallNewIsMonomorphic(CallNewFeedbackId()); 637 is_monomorphic_ = oracle->CallNewIsMonomorphic(CallNewFeedbackId());
761 if (is_monomorphic_) { 638 if (is_monomorphic_) {
762 target_ = oracle->GetCallNewTarget(CallNewFeedbackId()); 639 target_ = oracle->GetCallNewTarget(CallNewFeedbackId());
763 if (!allocation_site_.is_null()) { 640 if (!allocation_site_.is_null()) {
764 elements_kind_ = allocation_site_->GetElementsKind(); 641 elements_kind_ = allocation_site_->GetElementsKind();
765 } 642 }
766 } 643 }
(...skipping 506 matching lines...) Expand 10 before | Expand all | Expand 10 after
1273 OS::SNPrintF(buffer, "%d", Smi::cast(*value_)->value()); 1150 OS::SNPrintF(buffer, "%d", Smi::cast(*value_)->value());
1274 str = arr; 1151 str = arr;
1275 } else { 1152 } else {
1276 str = DoubleToCString(value_->Number(), buffer); 1153 str = DoubleToCString(value_->Number(), buffer);
1277 } 1154 }
1278 return isolate_->factory()->NewStringFromAscii(CStrVector(str)); 1155 return isolate_->factory()->NewStringFromAscii(CStrVector(str));
1279 } 1156 }
1280 1157
1281 1158
1282 } } // namespace v8::internal 1159 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « src/ast.h ('k') | src/code-stubs.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698