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

Side by Side Diff: src/ic.cc

Issue 157543002: A64: Synchronize with r18581. (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.cc » ('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 130 matching lines...) Expand 10 before | Expand all | Expand 10 after
141 #ifdef DEBUG 141 #ifdef DEBUG
142 StackFrameIterator it(isolate); 142 StackFrameIterator it(isolate);
143 for (int i = 0; i < depth + 1; i++) it.Advance(); 143 for (int i = 0; i < depth + 1; i++) it.Advance();
144 StackFrame* frame = it.frame(); 144 StackFrame* frame = it.frame();
145 ASSERT(fp == frame->fp() && pc_address == frame->pc_address()); 145 ASSERT(fp == frame->fp() && pc_address == frame->pc_address());
146 #endif 146 #endif
147 fp_ = fp; 147 fp_ = fp;
148 pc_address_ = StackFrame::ResolveReturnAddressLocation(pc_address); 148 pc_address_ = StackFrame::ResolveReturnAddressLocation(pc_address);
149 target_ = handle(raw_target(), isolate); 149 target_ = handle(raw_target(), isolate);
150 state_ = target_->ic_state(); 150 state_ = target_->ic_state();
151 extra_ic_state_ = target_->needs_extended_extra_ic_state(target_->kind())
152 ? target_->extended_extra_ic_state()
153 : target_->extra_ic_state();
151 } 154 }
152 155
153 156
154 #ifdef ENABLE_DEBUGGER_SUPPORT 157 #ifdef ENABLE_DEBUGGER_SUPPORT
155 Address IC::OriginalCodeAddress() const { 158 Address IC::OriginalCodeAddress() const {
156 HandleScope scope(isolate()); 159 HandleScope scope(isolate());
157 // Compute the JavaScript frame for the frame pointer of this IC 160 // Compute the JavaScript frame for the frame pointer of this IC
158 // structure. We need this to be able to find the function 161 // structure. We need this to be able to find the function
159 // corresponding to the frame. 162 // corresponding to the frame.
160 StackFrameIterator it(isolate()); 163 StackFrameIterator it(isolate());
(...skipping 87 matching lines...) Expand 10 before | Expand all | Expand 10 after
248 if (object->IsString()) { 251 if (object->IsString()) {
249 String* string = String::cast(*object); 252 String* string = String::cast(*object);
250 // Check there's the right string value or wrapper in the receiver slot. 253 // Check there's the right string value or wrapper in the receiver slot.
251 ASSERT(string == args[0] || string == JSValue::cast(args[0])->value()); 254 ASSERT(string == args[0] || string == JSValue::cast(args[0])->value());
252 // If we're in the default (fastest) state and the index is 255 // If we're in the default (fastest) state and the index is
253 // out of bounds, update the state to record this fact. 256 // out of bounds, update the state to record this fact.
254 if (StringStubState::decode(extra_ic_state()) == DEFAULT_STRING_STUB && 257 if (StringStubState::decode(extra_ic_state()) == DEFAULT_STRING_STUB &&
255 argc >= 1 && args[1]->IsNumber()) { 258 argc >= 1 && args[1]->IsNumber()) {
256 double index = DoubleToInteger(args.number_at(1)); 259 double index = DoubleToInteger(args.number_at(1));
257 if (index < 0 || index >= string->length()) { 260 if (index < 0 || index >= string->length()) {
258 extra_ic_state_ = 261 set_extra_ic_state(StringStubState::update(extra_ic_state(),
259 StringStubState::update(extra_ic_state(), 262 STRING_INDEX_OUT_OF_BOUNDS));
260 STRING_INDEX_OUT_OF_BOUNDS);
261 return true; 263 return true;
262 } 264 }
263 } 265 }
264 } 266 }
265 break; 267 break;
266 default: 268 default:
267 return false; 269 return false;
268 } 270 }
269 return false; 271 return false;
270 } 272 }
(...skipping 120 matching lines...) Expand 10 before | Expand all | Expand 10 after
391 // The builtins object is special. It only changes when JavaScript 393 // The builtins object is special. It only changes when JavaScript
392 // builtins are loaded lazily. It is important to keep inline 394 // builtins are loaded lazily. It is important to keep inline
393 // caches for the builtins object monomorphic. Therefore, if we get 395 // caches for the builtins object monomorphic. Therefore, if we get
394 // an inline cache miss for the builtins object after lazily loading 396 // an inline cache miss for the builtins object after lazily loading
395 // JavaScript builtins, we return uninitialized as the state to 397 // JavaScript builtins, we return uninitialized as the state to
396 // force the inline cache back to monomorphic state. 398 // force the inline cache back to monomorphic state.
397 if (receiver->IsJSBuiltinsObject()) state_ = UNINITIALIZED; 399 if (receiver->IsJSBuiltinsObject()) state_ = UNINITIALIZED;
398 } 400 }
399 401
400 402
401 RelocInfo::Mode IC::ComputeMode() {
402 Address addr = address();
403 Code* code = Code::cast(isolate()->FindCodeObject(addr));
404 for (RelocIterator it(code, RelocInfo::kCodeTargetMask);
405 !it.done(); it.next()) {
406 RelocInfo* info = it.rinfo();
407 if (info->pc() == addr) return info->rmode();
408 }
409 UNREACHABLE();
410 return RelocInfo::NONE32;
411 }
412
413
414 Failure* IC::TypeError(const char* type, 403 Failure* IC::TypeError(const char* type,
415 Handle<Object> object, 404 Handle<Object> object,
416 Handle<Object> key) { 405 Handle<Object> key) {
417 HandleScope scope(isolate()); 406 HandleScope scope(isolate());
418 Handle<Object> args[2] = { key, object }; 407 Handle<Object> args[2] = { key, object };
419 Handle<Object> error = isolate()->factory()->NewTypeError( 408 Handle<Object> error = isolate()->factory()->NewTypeError(
420 type, HandleVector(args, 2)); 409 type, HandleVector(args, 2));
421 return isolate()->Throw(*error); 410 return isolate()->Throw(*error);
422 } 411 }
423 412
(...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after
493 // Clearing these is tricky and does not 482 // Clearing these is tricky and does not
494 // make any performance difference. 483 // make any performance difference.
495 return; 484 return;
496 default: UNREACHABLE(); 485 default: UNREACHABLE();
497 } 486 }
498 } 487 }
499 488
500 489
501 void CallICBase::Clear(Address address, Code* target) { 490 void CallICBase::Clear(Address address, Code* target) {
502 if (IsCleared(target)) return; 491 if (IsCleared(target)) return;
503 bool contextual = CallICBase::Contextual::decode(target->extra_ic_state()); 492 ContextualMode mode = IC::GetContextualMode(target->extra_ic_state());
504 Code* code = 493 Code* code = target->GetIsolate()->stub_cache()->FindCallInitialize(
505 target->GetIsolate()->stub_cache()->FindCallInitialize( 494 target->arguments_count(), mode, target->kind());
506 target->arguments_count(),
507 contextual ? RelocInfo::CODE_TARGET_CONTEXT : RelocInfo::CODE_TARGET,
508 target->kind());
509 SetTargetAtAddress(address, code); 495 SetTargetAtAddress(address, code);
510 } 496 }
511 497
512 498
513 void KeyedLoadIC::Clear(Isolate* isolate, Address address, Code* target) { 499 void KeyedLoadIC::Clear(Isolate* isolate, Address address, Code* target) {
514 if (IsCleared(target)) return; 500 if (IsCleared(target)) return;
515 // Make sure to also clear the map used in inline fast cases. If we 501 // Make sure to also clear the map used in inline fast cases. If we
516 // do not clear these maps, cached code can keep objects alive 502 // do not clear these maps, cached code can keep objects alive
517 // through the embedded maps. 503 // through the embedded maps.
518 SetTargetAtAddress(address, *pre_monomorphic_stub(isolate)); 504 SetTargetAtAddress(address, *pre_monomorphic_stub(isolate));
519 } 505 }
520 506
521 507
522 void LoadIC::Clear(Isolate* isolate, Address address, Code* target) { 508 void LoadIC::Clear(Isolate* isolate, Address address, Code* target) {
523 if (IsCleared(target)) return; 509 if (IsCleared(target)) return;
524 SetTargetAtAddress(address, *pre_monomorphic_stub(isolate)); 510 Code* code = target->GetIsolate()->stub_cache()->FindPreMonomorphicIC(
511 Code::LOAD_IC, target->extra_ic_state());
512 SetTargetAtAddress(address, code);
525 } 513 }
526 514
527 515
528 void StoreIC::Clear(Isolate* isolate, Address address, Code* target) { 516 void StoreIC::Clear(Isolate* isolate, Address address, Code* target) {
529 if (IsCleared(target)) return; 517 if (IsCleared(target)) return;
530 SetTargetAtAddress(address, 518 Code* code = target->GetIsolate()->stub_cache()->FindPreMonomorphicIC(
531 *pre_monomorphic_stub( 519 Code::STORE_IC, target->extra_ic_state());
532 isolate, StoreIC::GetStrictMode(target->extra_ic_state()))); 520 SetTargetAtAddress(address, code);
533 } 521 }
534 522
535 523
536 void KeyedStoreIC::Clear(Isolate* isolate, Address address, Code* target) { 524 void KeyedStoreIC::Clear(Isolate* isolate, Address address, Code* target) {
537 if (IsCleared(target)) return; 525 if (IsCleared(target)) return;
538 SetTargetAtAddress(address, 526 SetTargetAtAddress(address,
539 *pre_monomorphic_stub( 527 *pre_monomorphic_stub(
540 isolate, StoreIC::GetStrictMode(target->extra_ic_state()))); 528 isolate, StoreIC::GetStrictMode(target->extra_ic_state())));
541 } 529 }
542 530
(...skipping 459 matching lines...) Expand 10 before | Expand all | Expand 10 after
1002 } 990 }
1003 991
1004 Handle<Code> ic = isolate()->stub_cache()->ComputePolymorphicIC( 992 Handle<Code> ic = isolate()->stub_cache()->ComputePolymorphicIC(
1005 &types, &handlers, number_of_valid_types, name, extra_ic_state()); 993 &types, &handlers, number_of_valid_types, name, extra_ic_state());
1006 set_target(*ic); 994 set_target(*ic);
1007 return true; 995 return true;
1008 } 996 }
1009 997
1010 998
1011 Handle<Type> IC::CurrentTypeOf(Handle<Object> object, Isolate* isolate) { 999 Handle<Type> IC::CurrentTypeOf(Handle<Object> object, Isolate* isolate) {
1012 Type* type = object->IsJSGlobalObject() 1000 return object->IsJSGlobalObject()
1013 ? Type::Constant(Handle<JSGlobalObject>::cast(object)) 1001 ? Type::Constant(Handle<JSGlobalObject>::cast(object), isolate)
1014 : Type::OfCurrently(object); 1002 : Type::OfCurrently(object, isolate);
1015 return handle(type, isolate);
1016 } 1003 }
1017 1004
1018 1005
1019 Handle<Map> IC::TypeToMap(Type* type, Isolate* isolate) { 1006 Handle<Map> IC::TypeToMap(Type* type, Isolate* isolate) {
1020 if (type->Is(Type::Number())) return isolate->factory()->heap_number_map(); 1007 if (type->Is(Type::Number())) return isolate->factory()->heap_number_map();
1021 if (type->Is(Type::Boolean())) return isolate->factory()->oddball_map(); 1008 if (type->Is(Type::Boolean())) return isolate->factory()->oddball_map();
1022 if (type->IsConstant()) { 1009 if (type->IsConstant()) {
1023 return handle(Handle<JSGlobalObject>::cast(type->AsConstant())->map()); 1010 return handle(Handle<JSGlobalObject>::cast(type->AsConstant())->map());
1024 } 1011 }
1025 ASSERT(type->IsClass()); 1012 ASSERT(type->IsClass());
1026 return type->AsClass(); 1013 return type->AsClass();
1027 } 1014 }
1028 1015
1029 1016
1030 Type* IC::MapToType(Handle<Map> map) { 1017 Handle<Type> IC::MapToType(Handle<Map> map) {
1031 if (map->instance_type() == HEAP_NUMBER_TYPE) return Type::Number(); 1018 Isolate* isolate = map->GetIsolate();
1019 if (map->instance_type() == HEAP_NUMBER_TYPE) return Type::Number(isolate);
1032 // The only oddballs that can be recorded in ICs are booleans. 1020 // The only oddballs that can be recorded in ICs are booleans.
1033 if (map->instance_type() == ODDBALL_TYPE) return Type::Boolean(); 1021 if (map->instance_type() == ODDBALL_TYPE) return Type::Boolean(isolate);
1034 return Type::Class(map); 1022 return Type::Class(map, isolate);
1035 } 1023 }
1036 1024
1037 1025
1038 void IC::UpdateMonomorphicIC(Handle<Type> type, 1026 void IC::UpdateMonomorphicIC(Handle<Type> type,
1039 Handle<Code> handler, 1027 Handle<Code> handler,
1040 Handle<String> name) { 1028 Handle<String> name) {
1041 if (!handler->is_handler()) return set_target(*handler); 1029 if (!handler->is_handler()) return set_target(*handler);
1042 Handle<Code> ic = isolate()->stub_cache()->ComputeMonomorphicIC( 1030 Handle<Code> ic = isolate()->stub_cache()->ComputeMonomorphicIC(
1043 name, type, handler, extra_ic_state()); 1031 name, type, handler, extra_ic_state());
1044 set_target(*ic); 1032 set_target(*ic);
1045 } 1033 }
1046 1034
1047 1035
1048 void IC::CopyICToMegamorphicCache(Handle<String> name) { 1036 void IC::CopyICToMegamorphicCache(Handle<String> name) {
1049 TypeHandleList types; 1037 TypeHandleList types;
1050 CodeHandleList handlers; 1038 CodeHandleList handlers;
1051 target()->FindAllTypes(&types); 1039 target()->FindAllTypes(&types);
1052 if (!target()->FindHandlers(&handlers, types.length())) return; 1040 if (!target()->FindHandlers(&handlers, types.length())) return;
1053 for (int i = 0; i < types.length(); i++) { 1041 for (int i = 0; i < types.length(); i++) {
1054 UpdateMegamorphicCache(*types.at(i), *name, *handlers.at(i)); 1042 UpdateMegamorphicCache(*types.at(i), *name, *handlers.at(i));
1055 } 1043 }
1056 } 1044 }
1057 1045
1058 1046
1059 bool IC::IsTransitionOfMonomorphicTarget(Type* type) { 1047 bool IC::IsTransitionOfMonomorphicTarget(Handle<Type> type) {
1060 if (!type->IsClass()) return false; 1048 if (!type->IsClass()) return false;
1061 Map* receiver_map = *type->AsClass(); 1049 Map* receiver_map = *type->AsClass();
1062 Map* current_map = target()->FindFirstMap(); 1050 Map* current_map = target()->FindFirstMap();
1063 ElementsKind receiver_elements_kind = receiver_map->elements_kind(); 1051 ElementsKind receiver_elements_kind = receiver_map->elements_kind();
1064 bool more_general_transition = 1052 bool more_general_transition =
1065 IsMoreGeneralElementsKindTransition( 1053 IsMoreGeneralElementsKindTransition(
1066 current_map->elements_kind(), receiver_elements_kind); 1054 current_map->elements_kind(), receiver_elements_kind);
1067 Map* transitioned_map = more_general_transition 1055 Map* transitioned_map = more_general_transition
1068 ? current_map->LookupElementsTransitionMap(receiver_elements_kind) 1056 ? current_map->LookupElementsTransitionMap(receiver_elements_kind)
1069 : NULL; 1057 : NULL;
(...skipping 11 matching lines...) Expand all
1081 case MONOMORPHIC_PROTOTYPE_FAILURE: 1069 case MONOMORPHIC_PROTOTYPE_FAILURE:
1082 UpdateMonomorphicIC(type, code, name); 1070 UpdateMonomorphicIC(type, code, name);
1083 break; 1071 break;
1084 case MONOMORPHIC: { 1072 case MONOMORPHIC: {
1085 // For now, call stubs are allowed to rewrite to the same stub. This 1073 // For now, call stubs are allowed to rewrite to the same stub. This
1086 // happens e.g., when the field does not contain a function. 1074 // happens e.g., when the field does not contain a function.
1087 ASSERT(target()->is_call_stub() || 1075 ASSERT(target()->is_call_stub() ||
1088 target()->is_keyed_call_stub() || 1076 target()->is_keyed_call_stub() ||
1089 !target().is_identical_to(code)); 1077 !target().is_identical_to(code));
1090 Code* old_handler = target()->FindFirstHandler(); 1078 Code* old_handler = target()->FindFirstHandler();
1091 if (old_handler == *code && IsTransitionOfMonomorphicTarget(*type)) { 1079 if (old_handler == *code && IsTransitionOfMonomorphicTarget(type)) {
1092 UpdateMonomorphicIC(type, code, name); 1080 UpdateMonomorphicIC(type, code, name);
1093 break; 1081 break;
1094 } 1082 }
1095 // Fall through. 1083 // Fall through.
1096 } 1084 }
1097 case POLYMORPHIC: 1085 case POLYMORPHIC:
1098 if (!target()->is_keyed_stub()) { 1086 if (!target()->is_keyed_stub()) {
1099 if (UpdatePolymorphicIC(type, name, code)) break; 1087 if (UpdatePolymorphicIC(type, name, code)) break;
1100 CopyICToMegamorphicCache(name); 1088 CopyICToMegamorphicCache(name);
1101 } 1089 }
1102 set_target(*megamorphic_stub()); 1090 set_target(*megamorphic_stub());
1103 // Fall through. 1091 // Fall through.
1104 case MEGAMORPHIC: 1092 case MEGAMORPHIC:
1105 UpdateMegamorphicCache(*type, *name, *code); 1093 UpdateMegamorphicCache(*type, *name, *code);
1106 break; 1094 break;
1107 case DEBUG_STUB: 1095 case DEBUG_STUB:
1108 break; 1096 break;
1109 case GENERIC: 1097 case GENERIC:
1110 UNREACHABLE(); 1098 UNREACHABLE();
1111 break; 1099 break;
1112 } 1100 }
1113 } 1101 }
1114 1102
1115 1103
1104 Handle<Code> LoadIC::initialize_stub(Isolate* isolate, ContextualMode mode) {
1105 Handle<Code> ic = isolate->stub_cache()->ComputeLoad(
1106 UNINITIALIZED, IC::ComputeExtraICState(mode));
1107 return ic;
1108 }
1109
1110
1111 Handle<Code> LoadIC::pre_monomorphic_stub(Isolate* isolate,
1112 ContextualMode mode) {
1113 return isolate->stub_cache()->ComputeLoad(
1114 PREMONOMORPHIC, IC::ComputeExtraICState(mode));
1115 }
1116
1117
1118 Handle<Code> LoadIC::megamorphic_stub() {
1119 return isolate()->stub_cache()->ComputeLoad(
1120 MEGAMORPHIC, extra_ic_state());
1121 }
1122
1123
1116 Handle<Code> LoadIC::SimpleFieldLoad(int offset, 1124 Handle<Code> LoadIC::SimpleFieldLoad(int offset,
1117 bool inobject, 1125 bool inobject,
1118 Representation representation) { 1126 Representation representation) {
1119 if (kind() == Code::LOAD_IC) { 1127 if (kind() == Code::LOAD_IC) {
1120 LoadFieldStub stub(inobject, offset, representation); 1128 LoadFieldStub stub(inobject, offset, representation);
1121 return stub.GetCode(isolate()); 1129 return stub.GetCode(isolate());
1122 } else { 1130 } else {
1123 KeyedLoadFieldStub stub(inobject, offset, representation); 1131 KeyedLoadFieldStub stub(inobject, offset, representation);
1124 return stub.GetCode(isolate()); 1132 return stub.GetCode(isolate());
1125 } 1133 }
(...skipping 457 matching lines...) Expand 10 before | Expand all | Expand 10 after
1583 } 1591 }
1584 1592
1585 // Set the property. 1593 // Set the property.
1586 Handle<Object> result = JSReceiver::SetProperty( 1594 Handle<Object> result = JSReceiver::SetProperty(
1587 receiver, name, value, NONE, strict_mode(), store_mode); 1595 receiver, name, value, NONE, strict_mode(), store_mode);
1588 RETURN_IF_EMPTY_HANDLE(isolate(), result); 1596 RETURN_IF_EMPTY_HANDLE(isolate(), result);
1589 return *result; 1597 return *result;
1590 } 1598 }
1591 1599
1592 1600
1601 Handle<Code> StoreIC::initialize_stub(Isolate* isolate,
1602 StrictModeFlag strict_mode,
1603 ContextualMode mode) {
1604 ExtraICState extra_state = ComputeExtraICState(strict_mode, mode);
1605 Handle<Code> ic = isolate->stub_cache()->ComputeStore(
1606 UNINITIALIZED, extra_state);
1607 return ic;
1608 }
1609
1610
1611 Handle<Code> StoreIC::megamorphic_stub() {
1612 return isolate()->stub_cache()->ComputeStore(MEGAMORPHIC, extra_ic_state());
1613 }
1614
1615
1616 Handle<Code> StoreIC::generic_stub() const {
1617 return isolate()->stub_cache()->ComputeStore(GENERIC, extra_ic_state());
1618 }
1619
1620
1621 Handle<Code> StoreIC::pre_monomorphic_stub(Isolate* isolate,
1622 StrictModeFlag strict_mode,
1623 ContextualMode contextual_mode) {
1624 ExtraICState state = StoreIC::ComputeExtraICState(strict_mode,
1625 contextual_mode);
1626 return isolate->stub_cache()->ComputeStore(PREMONOMORPHIC, state);
1627 }
1628
1629
1593 void StoreIC::UpdateCaches(LookupResult* lookup, 1630 void StoreIC::UpdateCaches(LookupResult* lookup,
1594 Handle<JSObject> receiver, 1631 Handle<JSObject> receiver,
1595 Handle<String> name, 1632 Handle<String> name,
1596 Handle<Object> value) { 1633 Handle<Object> value) {
1597 ASSERT(lookup->IsFound()); 1634 ASSERT(lookup->IsFound());
1598 1635
1599 // These are not cacheable, so we never see such LookupResults here. 1636 // These are not cacheable, so we never see such LookupResults here.
1600 ASSERT(!lookup->IsHandler()); 1637 ASSERT(!lookup->IsHandler());
1601 1638
1602 Handle<Code> code = ComputeHandler(lookup, receiver, name, value); 1639 Handle<Code> code = ComputeHandler(lookup, receiver, name, value);
(...skipping 973 matching lines...) Expand 10 before | Expand all | Expand 10 after
2576 GENERATE(Token::MOD, SMI, 2048, SMI, NO_OVERWRITE); 2613 GENERATE(Token::MOD, SMI, 2048, SMI, NO_OVERWRITE);
2577 #undef GENERATE 2614 #undef GENERATE
2578 } 2615 }
2579 2616
2580 2617
2581 Handle<Type> BinaryOpIC::State::GetResultType(Isolate* isolate) const { 2618 Handle<Type> BinaryOpIC::State::GetResultType(Isolate* isolate) const {
2582 Kind result_kind = result_kind_; 2619 Kind result_kind = result_kind_;
2583 if (HasSideEffects()) { 2620 if (HasSideEffects()) {
2584 result_kind = NONE; 2621 result_kind = NONE;
2585 } else if (result_kind == GENERIC && op_ == Token::ADD) { 2622 } else if (result_kind == GENERIC && op_ == Token::ADD) {
2586 return handle(Type::Union(handle(Type::Number(), isolate), 2623 return Type::Union(Type::Number(isolate), Type::String(isolate), isolate);
2587 handle(Type::String(), isolate)), isolate);
2588 } else if (result_kind == NUMBER && op_ == Token::SHR) { 2624 } else if (result_kind == NUMBER && op_ == Token::SHR) {
2589 return handle(Type::Unsigned32(), isolate); 2625 return Type::Unsigned32(isolate);
2590 } 2626 }
2591 ASSERT_NE(GENERIC, result_kind); 2627 ASSERT_NE(GENERIC, result_kind);
2592 return KindToType(result_kind, isolate); 2628 return KindToType(result_kind, isolate);
2593 } 2629 }
2594 2630
2595 2631
2596 void BinaryOpIC::State::Print(StringStream* stream) const { 2632 void BinaryOpIC::State::Print(StringStream* stream) const {
2597 stream->Add("(%s", Token::Name(op_)); 2633 stream->Add("(%s", Token::Name(op_));
2598 if (mode_ == OVERWRITE_LEFT) stream->Add("_ReuseLeft"); 2634 if (mode_ == OVERWRITE_LEFT) stream->Add("_ReuseLeft");
2599 else if (mode_ == OVERWRITE_RIGHT) stream->Add("_ReuseRight"); 2635 else if (mode_ == OVERWRITE_RIGHT) stream->Add("_ReuseRight");
(...skipping 114 matching lines...) Expand 10 before | Expand all | Expand 10 after
2714 case STRING: return "String"; 2750 case STRING: return "String";
2715 case GENERIC: return "Generic"; 2751 case GENERIC: return "Generic";
2716 } 2752 }
2717 UNREACHABLE(); 2753 UNREACHABLE();
2718 return NULL; 2754 return NULL;
2719 } 2755 }
2720 2756
2721 2757
2722 // static 2758 // static
2723 Handle<Type> BinaryOpIC::State::KindToType(Kind kind, Isolate* isolate) { 2759 Handle<Type> BinaryOpIC::State::KindToType(Kind kind, Isolate* isolate) {
2724 Type* type = NULL;
2725 switch (kind) { 2760 switch (kind) {
2726 case NONE: type = Type::None(); break; 2761 case NONE: return Type::None(isolate);
2727 case SMI: type = Type::Smi(); break; 2762 case SMI: return Type::Smi(isolate);
2728 case INT32: type = Type::Signed32(); break; 2763 case INT32: return Type::Signed32(isolate);
2729 case NUMBER: type = Type::Number(); break; 2764 case NUMBER: return Type::Number(isolate);
2730 case STRING: type = Type::String(); break; 2765 case STRING: return Type::String(isolate);
2731 case GENERIC: type = Type::Any(); break; 2766 case GENERIC: return Type::Any(isolate);
2732 } 2767 }
2733 return handle(type, isolate); 2768 UNREACHABLE();
2769 return Handle<Type>();
2734 } 2770 }
2735 2771
2736 2772
2737 MaybeObject* BinaryOpIC::Transition(Handle<AllocationSite> allocation_site, 2773 MaybeObject* BinaryOpIC::Transition(Handle<AllocationSite> allocation_site,
2738 Handle<Object> left, 2774 Handle<Object> left,
2739 Handle<Object> right) { 2775 Handle<Object> right) {
2740 State state(target()->extended_extra_ic_state()); 2776 State state(target()->extended_extra_ic_state());
2741 2777
2742 // Compute the actual result using the builtin for the binary operation. 2778 // Compute the actual result using the builtin for the binary operation.
2743 Object* builtin = isolate()->js_builtins_object()->javascript_builtin( 2779 Object* builtin = isolate()->js_builtins_object()->javascript_builtin(
(...skipping 114 matching lines...) Expand 10 before | Expand all | Expand 10 after
2858 UNREACHABLE(); 2894 UNREACHABLE();
2859 return NULL; 2895 return NULL;
2860 } 2896 }
2861 2897
2862 2898
2863 Handle<Type> CompareIC::StateToType( 2899 Handle<Type> CompareIC::StateToType(
2864 Isolate* isolate, 2900 Isolate* isolate,
2865 CompareIC::State state, 2901 CompareIC::State state,
2866 Handle<Map> map) { 2902 Handle<Map> map) {
2867 switch (state) { 2903 switch (state) {
2868 case CompareIC::UNINITIALIZED: 2904 case CompareIC::UNINITIALIZED: return Type::None(isolate);
2869 return handle(Type::None(), isolate); 2905 case CompareIC::SMI: return Type::Smi(isolate);
2870 case CompareIC::SMI: 2906 case CompareIC::NUMBER: return Type::Number(isolate);
2871 return handle(Type::Smi(), isolate); 2907 case CompareIC::STRING: return Type::String(isolate);
2872 case CompareIC::NUMBER:
2873 return handle(Type::Number(), isolate);
2874 case CompareIC::STRING:
2875 return handle(Type::String(), isolate);
2876 case CompareIC::INTERNALIZED_STRING: 2908 case CompareIC::INTERNALIZED_STRING:
2877 return handle(Type::InternalizedString(), isolate); 2909 return Type::InternalizedString(isolate);
2878 case CompareIC::UNIQUE_NAME: 2910 case CompareIC::UNIQUE_NAME: return Type::UniqueName(isolate);
2879 return handle(Type::UniqueName(), isolate); 2911 case CompareIC::OBJECT: return Type::Receiver(isolate);
2880 case CompareIC::OBJECT:
2881 return handle(Type::Receiver(), isolate);
2882 case CompareIC::KNOWN_OBJECT: 2912 case CompareIC::KNOWN_OBJECT:
2883 return handle( 2913 return map.is_null()
2884 map.is_null() ? Type::Receiver() : Type::Class(map), isolate); 2914 ? Type::Receiver(isolate) : Type::Class(map, isolate);
2885 case CompareIC::GENERIC: 2915 case CompareIC::GENERIC: return Type::Any(isolate);
2886 return handle(Type::Any(), isolate);
2887 } 2916 }
2888 UNREACHABLE(); 2917 UNREACHABLE();
2889 return Handle<Type>(); 2918 return Handle<Type>();
2890 } 2919 }
2891 2920
2892 2921
2893 void CompareIC::StubInfoToType(int stub_minor_key, 2922 void CompareIC::StubInfoToType(int stub_minor_key,
2894 Handle<Type>* left_type, 2923 Handle<Type>* left_type,
2895 Handle<Type>* right_type, 2924 Handle<Type>* right_type,
2896 Handle<Type>* overall_type, 2925 Handle<Type>* overall_type,
(...skipping 295 matching lines...) Expand 10 before | Expand all | Expand 10 after
3192 #undef ADDR 3221 #undef ADDR
3193 }; 3222 };
3194 3223
3195 3224
3196 Address IC::AddressFromUtilityId(IC::UtilityId id) { 3225 Address IC::AddressFromUtilityId(IC::UtilityId id) {
3197 return IC_utilities[id]; 3226 return IC_utilities[id];
3198 } 3227 }
3199 3228
3200 3229
3201 } } // namespace v8::internal 3230 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « src/ic.h ('k') | src/isolate.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698