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

Side by Side Diff: src/ic.cc

Issue 141363005: A64: Synchronize with r15204. (Closed) Base URL: https://v8.googlecode.com/svn/branches/experimental/a64
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/incremental-marking.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 668 matching lines...) Expand 10 before | Expand all | Expand 10 after
679 return isolate()->stub_cache()->ComputeCallConstant( 679 return isolate()->stub_cache()->ComputeCallConstant(
680 argc, kind_, extra_state, name, object, holder, function); 680 argc, kind_, extra_state, name, object, holder, function);
681 } 681 }
682 case NORMAL: { 682 case NORMAL: {
683 // If we return a null handle, the IC will not be patched. 683 // If we return a null handle, the IC will not be patched.
684 if (!object->IsJSObject()) return Handle<Code>::null(); 684 if (!object->IsJSObject()) return Handle<Code>::null();
685 Handle<JSObject> receiver = Handle<JSObject>::cast(object); 685 Handle<JSObject> receiver = Handle<JSObject>::cast(object);
686 686
687 if (holder->IsGlobalObject()) { 687 if (holder->IsGlobalObject()) {
688 Handle<GlobalObject> global = Handle<GlobalObject>::cast(holder); 688 Handle<GlobalObject> global = Handle<GlobalObject>::cast(holder);
689 Handle<JSGlobalPropertyCell> cell( 689 Handle<PropertyCell> cell(
690 global->GetPropertyCell(lookup), isolate()); 690 global->GetPropertyCell(lookup), isolate());
691 if (!cell->value()->IsJSFunction()) return Handle<Code>::null(); 691 if (!cell->value()->IsJSFunction()) return Handle<Code>::null();
692 Handle<JSFunction> function(JSFunction::cast(cell->value())); 692 Handle<JSFunction> function(JSFunction::cast(cell->value()));
693 return isolate()->stub_cache()->ComputeCallGlobal( 693 return isolate()->stub_cache()->ComputeCallGlobal(
694 argc, kind_, extra_state, name, receiver, global, cell, function); 694 argc, kind_, extra_state, name, receiver, global, cell, function);
695 } else { 695 } else {
696 // There is only one shared stub for calling normalized 696 // There is only one shared stub for calling normalized
697 // properties. It does not traverse the prototype chain, so the 697 // properties. It does not traverse the prototype chain, so the
698 // property must be found in the receiver for the stub to be 698 // property must be found in the receiver for the stub to be
699 // applicable. 699 // applicable.
(...skipping 229 matching lines...) Expand 10 before | Expand all | Expand 10 after
929 929
930 // If we did not find a property, check if we need to throw an exception. 930 // If we did not find a property, check if we need to throw an exception.
931 if (!lookup.IsFound()) { 931 if (!lookup.IsFound()) {
932 if (IsUndeclaredGlobal(object)) { 932 if (IsUndeclaredGlobal(object)) {
933 return ReferenceError("not_defined", name); 933 return ReferenceError("not_defined", name);
934 } 934 }
935 LOG(isolate(), SuspectReadEvent(*name, *object)); 935 LOG(isolate(), SuspectReadEvent(*name, *object));
936 } 936 }
937 937
938 // Update inline cache and stub cache. 938 // Update inline cache and stub cache.
939 if (FLAG_use_ic) { 939 if (FLAG_use_ic) UpdateCaches(&lookup, state, object, name);
940 if (!object->IsJSObject()) {
941 // TODO(jkummerow): It would be nice to support non-JSObjects in
942 // UpdateCaches, then we wouldn't need to go generic here.
943 set_target(*generic_stub());
944 } else {
945 UpdateCaches(&lookup, state, object, name);
946 }
947 }
948 940
949 PropertyAttributes attr; 941 PropertyAttributes attr;
950 if (lookup.IsInterceptor() || lookup.IsHandler()) { 942 if (lookup.IsInterceptor() || lookup.IsHandler()) {
951 // Get the property. 943 // Get the property.
952 Handle<Object> result = 944 Handle<Object> result =
953 Object::GetProperty(object, object, &lookup, name, &attr); 945 Object::GetProperty(object, object, &lookup, name, &attr);
954 RETURN_IF_EMPTY_HANDLE(isolate(), result); 946 RETURN_IF_EMPTY_HANDLE(isolate(), result);
955 // If the property is not present, check if we need to throw an 947 // If the property is not present, check if we need to throw an
956 // exception. 948 // exception.
957 if (attr == ABSENT && IsUndeclaredGlobal(object)) { 949 if (attr == ABSENT && IsUndeclaredGlobal(object)) {
(...skipping 239 matching lines...) Expand 10 before | Expand all | Expand 10 after
1197 break; 1189 break;
1198 } 1190 }
1199 } 1191 }
1200 1192
1201 1193
1202 void LoadIC::UpdateCaches(LookupResult* lookup, 1194 void LoadIC::UpdateCaches(LookupResult* lookup,
1203 State state, 1195 State state,
1204 Handle<Object> object, 1196 Handle<Object> object,
1205 Handle<String> name) { 1197 Handle<String> name) {
1206 // Bail out if the result is not cacheable. 1198 // Bail out if the result is not cacheable.
1207 if (!lookup->IsCacheable()) return; 1199 if (!lookup->IsCacheable()) {
1200 set_target(*generic_stub());
1201 return;
1202 }
1208 1203
1209 // Loading properties from values is not common, so don't try to 1204 // TODO(jkummerow): It would be nice to support non-JSObjects in
1210 // deal with non-JS objects here. 1205 // UpdateCaches, then we wouldn't need to go generic here.
1211 if (!object->IsJSObject()) return; 1206 if (!object->IsJSObject()) {
1207 set_target(*generic_stub());
1208 return;
1209 }
1212 1210
1213 Handle<JSObject> receiver = Handle<JSObject>::cast(object); 1211 Handle<JSObject> receiver = Handle<JSObject>::cast(object);
1214 Handle<Code> code; 1212 Handle<Code> code;
1215 if (state == UNINITIALIZED) { 1213 if (state == UNINITIALIZED) {
1216 // This is the first time we execute this inline cache. 1214 // This is the first time we execute this inline cache.
1217 // Set the target to the pre monomorphic stub to delay 1215 // Set the target to the pre monomorphic stub to delay
1218 // setting the monomorphic state. 1216 // setting the monomorphic state.
1219 code = pre_monomorphic_stub(); 1217 code = pre_monomorphic_stub();
1220 } else { 1218 } else {
1221 code = ComputeLoadHandler(lookup, receiver, name); 1219 code = ComputeLoadHandler(lookup, receiver, name);
1222 if (code.is_null()) return; 1220 if (code.is_null()) {
1221 set_target(*generic_stub());
1222 return;
1223 }
1223 } 1224 }
1224 1225
1225 PatchCache(state, kNonStrictMode, receiver, name, code); 1226 PatchCache(state, kNonStrictMode, receiver, name, code);
1226 TRACE_IC("LoadIC", name, state, target()); 1227 TRACE_IC("LoadIC", name, state, target());
1227 } 1228 }
1228 1229
1229 1230
1230 void IC::UpdateMegamorphicCache(Map* map, Name* name, Code* code) { 1231 void IC::UpdateMegamorphicCache(Map* map, Name* name, Code* code) {
1231 // Cache code holding map should be consistent with 1232 // Cache code holding map should be consistent with
1232 // GenerateMonomorphicCacheProbe. 1233 // GenerateMonomorphicCacheProbe.
(...skipping 17 matching lines...) Expand all
1250 name, receiver, holder, 1251 name, receiver, holder,
1251 lookup->GetFieldIndex(), lookup->representation()); 1252 lookup->GetFieldIndex(), lookup->representation());
1252 case CONSTANT_FUNCTION: { 1253 case CONSTANT_FUNCTION: {
1253 Handle<JSFunction> constant(lookup->GetConstantFunction()); 1254 Handle<JSFunction> constant(lookup->GetConstantFunction());
1254 return isolate()->stub_cache()->ComputeLoadConstant( 1255 return isolate()->stub_cache()->ComputeLoadConstant(
1255 name, receiver, holder, constant); 1256 name, receiver, holder, constant);
1256 } 1257 }
1257 case NORMAL: 1258 case NORMAL:
1258 if (holder->IsGlobalObject()) { 1259 if (holder->IsGlobalObject()) {
1259 Handle<GlobalObject> global = Handle<GlobalObject>::cast(holder); 1260 Handle<GlobalObject> global = Handle<GlobalObject>::cast(holder);
1260 Handle<JSGlobalPropertyCell> cell( 1261 Handle<PropertyCell> cell(
1261 global->GetPropertyCell(lookup), isolate()); 1262 global->GetPropertyCell(lookup), isolate());
1262 return isolate()->stub_cache()->ComputeLoadGlobal( 1263 return isolate()->stub_cache()->ComputeLoadGlobal(
1263 name, receiver, global, cell, lookup->IsDontDelete()); 1264 name, receiver, global, cell, lookup->IsDontDelete());
1264 } 1265 }
1265 // There is only one shared stub for loading normalized 1266 // There is only one shared stub for loading normalized
1266 // properties. It does not traverse the prototype chain, so the 1267 // properties. It does not traverse the prototype chain, so the
1267 // property must be found in the receiver for the stub to be 1268 // property must be found in the receiver for the stub to be
1268 // applicable. 1269 // applicable.
1269 if (!holder.is_identical_to(receiver)) break; 1270 if (!holder.is_identical_to(receiver)) break;
1270 return isolate()->stub_cache()->ComputeLoadNormal(name, receiver); 1271 return isolate()->stub_cache()->ComputeLoadNormal(name, receiver);
(...skipping 362 matching lines...) Expand 10 before | Expand all | Expand 10 after
1633 LookupResult lookup(isolate()); 1634 LookupResult lookup(isolate());
1634 if (LookupForWrite(receiver, name, value, &lookup, &state)) { 1635 if (LookupForWrite(receiver, name, value, &lookup, &state)) {
1635 if (FLAG_use_ic) { 1636 if (FLAG_use_ic) {
1636 UpdateCaches(&lookup, state, strict_mode, receiver, name, value); 1637 UpdateCaches(&lookup, state, strict_mode, receiver, name, value);
1637 } 1638 }
1638 } else if (strict_mode == kStrictMode && 1639 } else if (strict_mode == kStrictMode &&
1639 !(lookup.IsProperty() && lookup.IsReadOnly()) && 1640 !(lookup.IsProperty() && lookup.IsReadOnly()) &&
1640 IsUndeclaredGlobal(object)) { 1641 IsUndeclaredGlobal(object)) {
1641 // Strict mode doesn't allow setting non-existent global property. 1642 // Strict mode doesn't allow setting non-existent global property.
1642 return ReferenceError("not_defined", name); 1643 return ReferenceError("not_defined", name);
1644 } else if (FLAG_use_ic &&
1645 (lookup.IsNormal() ||
1646 (lookup.IsField() && lookup.CanHoldValue(value)))) {
1647 Handle<Code> stub = strict_mode == kStrictMode
1648 ? generic_stub_strict() : generic_stub();
1649 set_target(*stub);
1643 } 1650 }
1644 1651
1645 // Set the property. 1652 // Set the property.
1646 return JSReceiver::SetPropertyOrFail( 1653 return JSReceiver::SetPropertyOrFail(
1647 receiver, name, value, NONE, strict_mode, store_mode); 1654 receiver, name, value, NONE, strict_mode, store_mode);
1648 } 1655 }
1649 1656
1650 1657
1651 void StoreIC::UpdateCaches(LookupResult* lookup, 1658 void StoreIC::UpdateCaches(LookupResult* lookup,
1652 State state, 1659 State state,
1653 StrictModeFlag strict_mode, 1660 StrictModeFlag strict_mode,
1654 Handle<JSObject> receiver, 1661 Handle<JSObject> receiver,
1655 Handle<String> name, 1662 Handle<String> name,
1656 Handle<Object> value) { 1663 Handle<Object> value) {
1657 ASSERT(!receiver->IsJSGlobalProxy()); 1664 ASSERT(!receiver->IsJSGlobalProxy());
1658 ASSERT(lookup->IsFound()); 1665 ASSERT(lookup->IsFound());
1659 1666
1660 // These are not cacheable, so we never see such LookupResults here. 1667 // These are not cacheable, so we never see such LookupResults here.
1661 ASSERT(!lookup->IsHandler()); 1668 ASSERT(!lookup->IsHandler());
1662 1669
1663 Handle<Code> code = 1670 Handle<Code> code = ComputeStoreMonomorphic(
1664 ComputeStoreMonomorphic(lookup, strict_mode, receiver, name); 1671 lookup, strict_mode, receiver, name);
1665 if (code.is_null()) return; 1672 if (code.is_null()) {
1673 Handle<Code> stub = strict_mode == kStrictMode
1674 ? generic_stub_strict() : generic_stub();
1675 set_target(*stub);
1676 return;
1677 }
1666 1678
1667 PatchCache(state, strict_mode, receiver, name, code); 1679 PatchCache(state, strict_mode, receiver, name, code);
1668 TRACE_IC("StoreIC", name, state, target()); 1680 TRACE_IC("StoreIC", name, state, target());
1669 } 1681 }
1670 1682
1671 1683
1672 Handle<Code> StoreIC::ComputeStoreMonomorphic(LookupResult* lookup, 1684 Handle<Code> StoreIC::ComputeStoreMonomorphic(LookupResult* lookup,
1673 StrictModeFlag strict_mode, 1685 StrictModeFlag strict_mode,
1674 Handle<JSObject> receiver, 1686 Handle<JSObject> receiver,
1675 Handle<String> name) { 1687 Handle<String> name) {
1676 Handle<JSObject> holder(lookup->holder()); 1688 Handle<JSObject> holder(lookup->holder());
1677 switch (lookup->type()) { 1689 switch (lookup->type()) {
1678 case FIELD: 1690 case FIELD:
1679 return isolate()->stub_cache()->ComputeStoreField( 1691 return isolate()->stub_cache()->ComputeStoreField(
1680 name, receiver, lookup, strict_mode); 1692 name, receiver, lookup, strict_mode);
1681 case NORMAL: 1693 case NORMAL:
1682 if (receiver->IsGlobalObject()) { 1694 if (receiver->IsGlobalObject()) {
1683 // The stub generated for the global object picks the value directly 1695 // The stub generated for the global object picks the value directly
1684 // from the property cell. So the property must be directly on the 1696 // from the property cell. So the property must be directly on the
1685 // global object. 1697 // global object.
1686 Handle<GlobalObject> global = Handle<GlobalObject>::cast(receiver); 1698 Handle<GlobalObject> global = Handle<GlobalObject>::cast(receiver);
1687 Handle<JSGlobalPropertyCell> cell( 1699 Handle<PropertyCell> cell(
1688 global->GetPropertyCell(lookup), isolate()); 1700 global->GetPropertyCell(lookup), isolate());
1689 return isolate()->stub_cache()->ComputeStoreGlobal( 1701 return isolate()->stub_cache()->ComputeStoreGlobal(
1690 name, global, cell, strict_mode); 1702 name, global, cell, strict_mode);
1691 } 1703 }
1692 ASSERT(holder.is_identical_to(receiver)); 1704 ASSERT(holder.is_identical_to(receiver));
1693 return isolate()->stub_cache()->ComputeStoreNormal(strict_mode); 1705 return isolate()->stub_cache()->ComputeStoreNormal(strict_mode);
1694 case CALLBACKS: { 1706 case CALLBACKS: {
1695 Handle<Object> callback(lookup->GetCallbackObject(), isolate()); 1707 Handle<Object> callback(lookup->GetCallbackObject(), isolate());
1696 if (callback->IsExecutableAccessorInfo()) { 1708 if (callback->IsExecutableAccessorInfo()) {
1697 Handle<ExecutableAccessorInfo> info = 1709 Handle<ExecutableAccessorInfo> info =
(...skipping 28 matching lines...) Expand all
1726 case TRANSITION: { 1738 case TRANSITION: {
1727 // Explicitly pass in the receiver map since LookupForWrite may have 1739 // Explicitly pass in the receiver map since LookupForWrite may have
1728 // stored something else than the receiver in the holder. 1740 // stored something else than the receiver in the holder.
1729 Handle<Map> transition( 1741 Handle<Map> transition(
1730 lookup->GetTransitionTarget(receiver->map()), isolate()); 1742 lookup->GetTransitionTarget(receiver->map()), isolate());
1731 int descriptor = transition->LastAdded(); 1743 int descriptor = transition->LastAdded();
1732 1744
1733 DescriptorArray* target_descriptors = transition->instance_descriptors(); 1745 DescriptorArray* target_descriptors = transition->instance_descriptors();
1734 PropertyDetails details = target_descriptors->GetDetails(descriptor); 1746 PropertyDetails details = target_descriptors->GetDetails(descriptor);
1735 1747
1736 if (details.type() != FIELD || details.attributes() != NONE) break; 1748 if (details.type() == CALLBACKS || details.attributes() != NONE) break;
1737 1749
1738 return isolate()->stub_cache()->ComputeStoreTransition( 1750 return isolate()->stub_cache()->ComputeStoreTransition(
1739 name, receiver, lookup, transition, strict_mode); 1751 name, receiver, lookup, transition, strict_mode);
1740 } 1752 }
1741 case NONEXISTENT: 1753 case NONEXISTENT:
1742 case HANDLER: 1754 case HANDLER:
1743 UNREACHABLE(); 1755 UNREACHABLE();
1744 break; 1756 break;
1745 } 1757 }
1746 return Handle<Code>::null(); 1758 return Handle<Code>::null();
(...skipping 345 matching lines...) Expand 10 before | Expand all | Expand 10 after
2092 case TRANSITION: { 2104 case TRANSITION: {
2093 // Explicitly pass in the receiver map since LookupForWrite may have 2105 // Explicitly pass in the receiver map since LookupForWrite may have
2094 // stored something else than the receiver in the holder. 2106 // stored something else than the receiver in the holder.
2095 Handle<Map> transition( 2107 Handle<Map> transition(
2096 lookup->GetTransitionTarget(receiver->map()), isolate()); 2108 lookup->GetTransitionTarget(receiver->map()), isolate());
2097 int descriptor = transition->LastAdded(); 2109 int descriptor = transition->LastAdded();
2098 2110
2099 DescriptorArray* target_descriptors = transition->instance_descriptors(); 2111 DescriptorArray* target_descriptors = transition->instance_descriptors();
2100 PropertyDetails details = target_descriptors->GetDetails(descriptor); 2112 PropertyDetails details = target_descriptors->GetDetails(descriptor);
2101 2113
2102 if (details.type() == FIELD && details.attributes() == NONE) { 2114 if (details.type() != CALLBACKS && details.attributes() == NONE) {
2103 return isolate()->stub_cache()->ComputeKeyedStoreTransition( 2115 return isolate()->stub_cache()->ComputeKeyedStoreTransition(
2104 name, receiver, lookup, transition, strict_mode); 2116 name, receiver, lookup, transition, strict_mode);
2105 } 2117 }
2106 // fall through. 2118 // fall through.
2107 } 2119 }
2108 case NORMAL: 2120 case NORMAL:
2109 case CONSTANT_FUNCTION: 2121 case CONSTANT_FUNCTION:
2110 case CALLBACKS: 2122 case CALLBACKS:
2111 case INTERCEPTOR: 2123 case INTERCEPTOR:
2112 // Always rewrite to the generic case so that we do not 2124 // Always rewrite to the generic case so that we do not
(...skipping 288 matching lines...) Expand 10 before | Expand all | Expand 10 after
2401 case NUMBER: return "Number"; 2413 case NUMBER: return "Number";
2402 case GENERIC: return "Generic"; 2414 case GENERIC: return "Generic";
2403 default: return "Invalid"; 2415 default: return "Invalid";
2404 } 2416 }
2405 } 2417 }
2406 2418
2407 2419
2408 UnaryOpIC::State UnaryOpIC::ToState(TypeInfo type_info) { 2420 UnaryOpIC::State UnaryOpIC::ToState(TypeInfo type_info) {
2409 switch (type_info) { 2421 switch (type_info) {
2410 case UNINITIALIZED: 2422 case UNINITIALIZED:
2411 return ::v8::internal::UNINITIALIZED; 2423 return v8::internal::UNINITIALIZED;
2412 case SMI: 2424 case SMI:
2413 case NUMBER: 2425 case NUMBER:
2414 return MONOMORPHIC; 2426 return MONOMORPHIC;
2415 case GENERIC: 2427 case GENERIC:
2416 return ::v8::internal::GENERIC; 2428 return v8::internal::GENERIC;
2417 } 2429 }
2418 UNREACHABLE(); 2430 UNREACHABLE();
2419 return ::v8::internal::UNINITIALIZED; 2431 return v8::internal::UNINITIALIZED;
2420 } 2432 }
2421 2433
2434
2435 Handle<Type> UnaryOpIC::TypeInfoToType(TypeInfo type_info, Isolate* isolate) {
2436 switch (type_info) {
2437 case UNINITIALIZED:
2438 return handle(Type::None(), isolate);
2439 case SMI:
2440 return handle(Type::Integer31(), isolate);
2441 case NUMBER:
2442 return handle(Type::Number(), isolate);
2443 case GENERIC:
2444 return handle(Type::Any(), isolate);
2445 }
2446 UNREACHABLE();
2447 return handle(Type::Any(), isolate);
2448 }
2449
2450
2422 UnaryOpIC::TypeInfo UnaryOpIC::GetTypeInfo(Handle<Object> operand) { 2451 UnaryOpIC::TypeInfo UnaryOpIC::GetTypeInfo(Handle<Object> operand) {
2423 ::v8::internal::TypeInfo operand_type = 2452 v8::internal::TypeInfo operand_type =
2424 ::v8::internal::TypeInfo::TypeFromValue(operand); 2453 v8::internal::TypeInfo::FromValue(operand);
2425 if (operand_type.IsSmi()) { 2454 if (operand_type.IsSmi()) {
2426 return SMI; 2455 return SMI;
2427 } else if (operand_type.IsNumber()) { 2456 } else if (operand_type.IsNumber()) {
2428 return NUMBER; 2457 return NUMBER;
2429 } else { 2458 } else {
2430 return GENERIC; 2459 return GENERIC;
2431 } 2460 }
2432 } 2461 }
2433 2462
2434 2463
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after
2482 case STRING: 2511 case STRING:
2483 return MONOMORPHIC; 2512 return MONOMORPHIC;
2484 case GENERIC: 2513 case GENERIC:
2485 return ::v8::internal::GENERIC; 2514 return ::v8::internal::GENERIC;
2486 } 2515 }
2487 UNREACHABLE(); 2516 UNREACHABLE();
2488 return ::v8::internal::UNINITIALIZED; 2517 return ::v8::internal::UNINITIALIZED;
2489 } 2518 }
2490 2519
2491 2520
2521 Handle<Type> BinaryOpIC::TypeInfoToType(BinaryOpIC::TypeInfo binary_type,
2522 Isolate* isolate) {
2523 switch (binary_type) {
2524 case UNINITIALIZED:
2525 return handle(Type::None(), isolate);
2526 case SMI:
2527 return handle(Type::Integer31(), isolate);
2528 case INT32:
2529 return handle(Type::Integer32(), isolate);
2530 case NUMBER:
2531 return handle(Type::Number(), isolate);
2532 case ODDBALL:
2533 return handle(Type::Optional(
2534 handle(Type::Union(
2535 handle(Type::Number(), isolate),
2536 handle(Type::String(), isolate)), isolate)), isolate);
2537 case STRING:
2538 return handle(Type::String(), isolate);
2539 case GENERIC:
2540 return handle(Type::Any(), isolate);
2541 }
2542 UNREACHABLE();
2543 return handle(Type::Any(), isolate);
2544 }
2545
2546
2547 void BinaryOpIC::StubInfoToType(int minor_key,
2548 Handle<Type>* left,
2549 Handle<Type>* right,
2550 Handle<Type>* result,
2551 Isolate* isolate) {
2552 TypeInfo left_typeinfo, right_typeinfo, result_typeinfo;
2553 BinaryOpStub::decode_types_from_minor_key(
2554 minor_key, &left_typeinfo, &right_typeinfo, &result_typeinfo);
2555 *left = TypeInfoToType(left_typeinfo, isolate);
2556 *right = TypeInfoToType(right_typeinfo, isolate);
2557 *result = TypeInfoToType(result_typeinfo, isolate);
2558 }
2559
2560
2492 RUNTIME_FUNCTION(MaybeObject*, UnaryOp_Patch) { 2561 RUNTIME_FUNCTION(MaybeObject*, UnaryOp_Patch) {
2493 ASSERT(args.length() == 4); 2562 ASSERT(args.length() == 4);
2494 2563
2495 HandleScope scope(isolate); 2564 HandleScope scope(isolate);
2496 Handle<Object> operand = args.at<Object>(0); 2565 Handle<Object> operand = args.at<Object>(0);
2497 Token::Value op = static_cast<Token::Value>(args.smi_at(1)); 2566 Token::Value op = static_cast<Token::Value>(args.smi_at(1));
2498 UnaryOverwriteMode mode = static_cast<UnaryOverwriteMode>(args.smi_at(2)); 2567 UnaryOverwriteMode mode = static_cast<UnaryOverwriteMode>(args.smi_at(2));
2499 UnaryOpIC::TypeInfo previous_type = 2568 UnaryOpIC::TypeInfo previous_type =
2500 static_cast<UnaryOpIC::TypeInfo>(args.smi_at(3)); 2569 static_cast<UnaryOpIC::TypeInfo>(args.smi_at(3));
2501 2570
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after
2538 &caught_exception); 2607 &caught_exception);
2539 if (caught_exception) { 2608 if (caught_exception) {
2540 return Failure::Exception(); 2609 return Failure::Exception();
2541 } 2610 }
2542 return *result; 2611 return *result;
2543 } 2612 }
2544 2613
2545 2614
2546 static BinaryOpIC::TypeInfo TypeInfoFromValue(Handle<Object> value, 2615 static BinaryOpIC::TypeInfo TypeInfoFromValue(Handle<Object> value,
2547 Token::Value op) { 2616 Token::Value op) {
2548 ::v8::internal::TypeInfo type = 2617 v8::internal::TypeInfo type = v8::internal::TypeInfo::FromValue(value);
2549 ::v8::internal::TypeInfo::TypeFromValue(value);
2550 if (type.IsSmi()) return BinaryOpIC::SMI; 2618 if (type.IsSmi()) return BinaryOpIC::SMI;
2551 if (type.IsInteger32()) { 2619 if (type.IsInteger32()) {
2552 if (kSmiValueSize == 32) return BinaryOpIC::SMI; 2620 if (kSmiValueSize == 32) return BinaryOpIC::SMI;
2553 return BinaryOpIC::INT32; 2621 return BinaryOpIC::INT32;
2554 } 2622 }
2555 if (type.IsNumber()) return BinaryOpIC::NUMBER; 2623 if (type.IsNumber()) return BinaryOpIC::NUMBER;
2556 if (type.IsString()) return BinaryOpIC::STRING; 2624 if (type.IsString()) return BinaryOpIC::STRING;
2557 if (value->IsUndefined()) { 2625 if (value->IsUndefined()) {
2558 if (op == Token::BIT_AND || 2626 if (op == Token::BIT_AND ||
2559 op == Token::BIT_OR || 2627 op == Token::BIT_OR ||
(...skipping 200 matching lines...) Expand 10 before | Expand all | Expand 10 after
2760 switch (state) { 2828 switch (state) {
2761 case UNINITIALIZED: return "UNINITIALIZED"; 2829 case UNINITIALIZED: return "UNINITIALIZED";
2762 case SMI: return "SMI"; 2830 case SMI: return "SMI";
2763 case NUMBER: return "NUMBER"; 2831 case NUMBER: return "NUMBER";
2764 case INTERNALIZED_STRING: return "INTERNALIZED_STRING"; 2832 case INTERNALIZED_STRING: return "INTERNALIZED_STRING";
2765 case STRING: return "STRING"; 2833 case STRING: return "STRING";
2766 case UNIQUE_NAME: return "UNIQUE_NAME"; 2834 case UNIQUE_NAME: return "UNIQUE_NAME";
2767 case OBJECT: return "OBJECT"; 2835 case OBJECT: return "OBJECT";
2768 case KNOWN_OBJECT: return "KNOWN_OBJECT"; 2836 case KNOWN_OBJECT: return "KNOWN_OBJECT";
2769 case GENERIC: return "GENERIC"; 2837 case GENERIC: return "GENERIC";
2770 default:
2771 UNREACHABLE();
2772 return NULL;
2773 } 2838 }
2839 UNREACHABLE();
2840 return NULL;
2774 } 2841 }
2775 2842
2776 2843
2777 static CompareIC::State InputState(CompareIC::State old_state, 2844 Handle<Type> CompareIC::StateToType(
2778 Handle<Object> value) { 2845 Isolate* isolate,
2846 CompareIC::State state,
2847 Handle<Map> map) {
2848 switch (state) {
2849 case CompareIC::UNINITIALIZED:
2850 return handle(Type::None(), isolate);
2851 case CompareIC::SMI:
2852 return handle(Type::Integer31(), isolate);
2853 case CompareIC::NUMBER:
2854 return handle(Type::Number(), isolate);
2855 case CompareIC::STRING:
2856 return handle(Type::String(), isolate);
2857 case CompareIC::INTERNALIZED_STRING:
2858 return handle(Type::InternalizedString(), isolate);
2859 case CompareIC::UNIQUE_NAME:
2860 return handle(Type::UniqueName(), isolate);
2861 case CompareIC::OBJECT:
2862 return handle(Type::Receiver(), isolate);
2863 case CompareIC::KNOWN_OBJECT:
2864 return handle(
2865 map.is_null() ? Type::Receiver() : Type::Class(map), isolate);
2866 case CompareIC::GENERIC:
2867 return handle(Type::Any(), isolate);
2868 }
2869 UNREACHABLE();
2870 return Handle<Type>();
2871 }
2872
2873
2874 void CompareIC::StubInfoToType(int stub_minor_key,
2875 Handle<Type>* left_type,
2876 Handle<Type>* right_type,
2877 Handle<Type>* overall_type,
2878 Handle<Map> map,
2879 Isolate* isolate) {
2880 State left_state, right_state, handler_state;
2881 ICCompareStub::DecodeMinorKey(stub_minor_key, &left_state, &right_state,
2882 &handler_state, NULL);
2883 *left_type = StateToType(isolate, left_state);
2884 *right_type = StateToType(isolate, right_state);
2885 *overall_type = StateToType(isolate, handler_state, map);
2886 }
2887
2888
2889 CompareIC::State CompareIC::NewInputState(State old_state,
2890 Handle<Object> value) {
2779 switch (old_state) { 2891 switch (old_state) {
2780 case CompareIC::UNINITIALIZED: 2892 case UNINITIALIZED:
2781 if (value->IsSmi()) return CompareIC::SMI; 2893 if (value->IsSmi()) return SMI;
2782 if (value->IsHeapNumber()) return CompareIC::NUMBER; 2894 if (value->IsHeapNumber()) return NUMBER;
2783 if (value->IsInternalizedString()) return CompareIC::INTERNALIZED_STRING; 2895 if (value->IsInternalizedString()) return INTERNALIZED_STRING;
2784 if (value->IsString()) return CompareIC::STRING; 2896 if (value->IsString()) return STRING;
2785 if (value->IsSymbol()) return CompareIC::UNIQUE_NAME; 2897 if (value->IsSymbol()) return UNIQUE_NAME;
2786 if (value->IsJSObject()) return CompareIC::OBJECT; 2898 if (value->IsJSObject()) return OBJECT;
2787 break; 2899 break;
2788 case CompareIC::SMI: 2900 case SMI:
2789 if (value->IsSmi()) return CompareIC::SMI; 2901 if (value->IsSmi()) return SMI;
2790 if (value->IsHeapNumber()) return CompareIC::NUMBER; 2902 if (value->IsHeapNumber()) return NUMBER;
2791 break; 2903 break;
2792 case CompareIC::NUMBER: 2904 case NUMBER:
2793 if (value->IsNumber()) return CompareIC::NUMBER; 2905 if (value->IsNumber()) return NUMBER;
2794 break; 2906 break;
2795 case CompareIC::INTERNALIZED_STRING: 2907 case INTERNALIZED_STRING:
2796 if (value->IsInternalizedString()) return CompareIC::INTERNALIZED_STRING; 2908 if (value->IsInternalizedString()) return INTERNALIZED_STRING;
2797 if (value->IsString()) return CompareIC::STRING; 2909 if (value->IsString()) return STRING;
2798 if (value->IsSymbol()) return CompareIC::UNIQUE_NAME; 2910 if (value->IsSymbol()) return UNIQUE_NAME;
2799 break; 2911 break;
2800 case CompareIC::STRING: 2912 case STRING:
2801 if (value->IsString()) return CompareIC::STRING; 2913 if (value->IsString()) return STRING;
2802 break; 2914 break;
2803 case CompareIC::UNIQUE_NAME: 2915 case UNIQUE_NAME:
2804 if (value->IsUniqueName()) return CompareIC::UNIQUE_NAME; 2916 if (value->IsUniqueName()) return UNIQUE_NAME;
2805 break; 2917 break;
2806 case CompareIC::OBJECT: 2918 case OBJECT:
2807 if (value->IsJSObject()) return CompareIC::OBJECT; 2919 if (value->IsJSObject()) return OBJECT;
2808 break; 2920 break;
2809 case CompareIC::GENERIC: 2921 case GENERIC:
2810 break; 2922 break;
2811 case CompareIC::KNOWN_OBJECT: 2923 case KNOWN_OBJECT:
2812 UNREACHABLE(); 2924 UNREACHABLE();
2813 break; 2925 break;
2814 } 2926 }
2815 return CompareIC::GENERIC; 2927 return GENERIC;
2816 } 2928 }
2817 2929
2818 2930
2819 CompareIC::State CompareIC::TargetState(State old_state, 2931 CompareIC::State CompareIC::TargetState(State old_state,
2820 State old_left, 2932 State old_left,
2821 State old_right, 2933 State old_right,
2822 bool has_inlined_smi_code, 2934 bool has_inlined_smi_code,
2823 Handle<Object> x, 2935 Handle<Object> x,
2824 Handle<Object> y) { 2936 Handle<Object> y) {
2825 switch (old_state) { 2937 switch (old_state) {
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after
2878 UNREACHABLE(); 2990 UNREACHABLE();
2879 return GENERIC; // Make the compiler happy. 2991 return GENERIC; // Make the compiler happy.
2880 } 2992 }
2881 2993
2882 2994
2883 void CompareIC::UpdateCaches(Handle<Object> x, Handle<Object> y) { 2995 void CompareIC::UpdateCaches(Handle<Object> x, Handle<Object> y) {
2884 HandleScope scope(isolate()); 2996 HandleScope scope(isolate());
2885 State previous_left, previous_right, previous_state; 2997 State previous_left, previous_right, previous_state;
2886 ICCompareStub::DecodeMinorKey(target()->stub_info(), &previous_left, 2998 ICCompareStub::DecodeMinorKey(target()->stub_info(), &previous_left,
2887 &previous_right, &previous_state, NULL); 2999 &previous_right, &previous_state, NULL);
2888 State new_left = InputState(previous_left, x); 3000 State new_left = NewInputState(previous_left, x);
2889 State new_right = InputState(previous_right, y); 3001 State new_right = NewInputState(previous_right, y);
2890 State state = TargetState(previous_state, previous_left, previous_right, 3002 State state = TargetState(previous_state, previous_left, previous_right,
2891 HasInlinedSmiCode(address()), x, y); 3003 HasInlinedSmiCode(address()), x, y);
2892 ICCompareStub stub(op_, new_left, new_right, state); 3004 ICCompareStub stub(op_, new_left, new_right, state);
2893 if (state == KNOWN_OBJECT) { 3005 if (state == KNOWN_OBJECT) {
2894 stub.set_known_map( 3006 stub.set_known_map(
2895 Handle<Map>(Handle<JSObject>::cast(x)->map(), isolate())); 3007 Handle<Map>(Handle<JSObject>::cast(x)->map(), isolate()));
2896 } 3008 }
2897 set_target(*stub.GetCode(isolate())); 3009 set_target(*stub.GetCode(isolate()));
2898 3010
2899 #ifdef DEBUG 3011 #ifdef DEBUG
(...skipping 27 matching lines...) Expand all
2927 ic.UpdateCaches(args.at<Object>(0), args.at<Object>(1)); 3039 ic.UpdateCaches(args.at<Object>(0), args.at<Object>(1));
2928 return ic.target(); 3040 return ic.target();
2929 } 3041 }
2930 3042
2931 3043
2932 void CompareNilIC::Clear(Address address, Code* target) { 3044 void CompareNilIC::Clear(Address address, Code* target) {
2933 if (target->ic_state() == UNINITIALIZED) return; 3045 if (target->ic_state() == UNINITIALIZED) return;
2934 Code::ExtraICState state = target->extended_extra_ic_state(); 3046 Code::ExtraICState state = target->extended_extra_ic_state();
2935 3047
2936 CompareNilICStub stub(state, HydrogenCodeStub::UNINITIALIZED); 3048 CompareNilICStub stub(state, HydrogenCodeStub::UNINITIALIZED);
2937 stub.ClearTypes(); 3049 stub.ClearState();
2938 3050
2939 Code* code = NULL; 3051 Code* code = NULL;
2940 CHECK(stub.FindCodeInCache(&code, target->GetIsolate())); 3052 CHECK(stub.FindCodeInCache(&code, target->GetIsolate()));
2941 3053
2942 SetTargetAtAddress(address, code); 3054 SetTargetAtAddress(address, code);
2943 } 3055 }
2944 3056
2945 3057
2946 MaybeObject* CompareNilIC::DoCompareNilSlow(NilValue nil, 3058 MaybeObject* CompareNilIC::DoCompareNilSlow(NilValue nil,
2947 Handle<Object> object) { 3059 Handle<Object> object) {
2948 if (object->IsNull() || object->IsUndefined()) { 3060 if (object->IsNull() || object->IsUndefined()) {
2949 return Smi::FromInt(true); 3061 return Smi::FromInt(true);
2950 } 3062 }
2951 return Smi::FromInt(object->IsUndetectableObject()); 3063 return Smi::FromInt(object->IsUndetectableObject());
2952 } 3064 }
2953 3065
2954 3066
2955 MaybeObject* CompareNilIC::CompareNil(Handle<Object> object) { 3067 MaybeObject* CompareNilIC::CompareNil(Handle<Object> object) {
2956 Code::ExtraICState extra_ic_state = target()->extended_extra_ic_state(); 3068 Code::ExtraICState extra_ic_state = target()->extended_extra_ic_state();
2957 3069
2958 CompareNilICStub stub(extra_ic_state); 3070 CompareNilICStub stub(extra_ic_state);
2959 3071
2960 // Extract the current supported types from the patched IC and calculate what 3072 // Extract the current supported types from the patched IC and calculate what
2961 // types must be supported as a result of the miss. 3073 // types must be supported as a result of the miss.
2962 bool already_monomorphic = stub.IsMonomorphic(); 3074 bool already_monomorphic = stub.IsMonomorphic();
2963 3075
2964 CompareNilICStub::Types old_types = stub.GetTypes(); 3076 CompareNilICStub::State old_state = stub.GetState();
2965 stub.Record(object); 3077 stub.Record(object);
2966 old_types.TraceTransition(stub.GetTypes()); 3078 old_state.TraceTransition(stub.GetState());
2967 3079
2968 NilValue nil = stub.GetNilValue(); 3080 NilValue nil = stub.GetNilValue();
2969 3081
2970 // Find or create the specialized stub to support the new set of types. 3082 // Find or create the specialized stub to support the new set of types.
2971 Handle<Code> code; 3083 Handle<Code> code;
2972 if (stub.IsMonomorphic()) { 3084 if (stub.IsMonomorphic()) {
2973 Handle<Map> monomorphic_map(already_monomorphic 3085 Handle<Map> monomorphic_map(already_monomorphic
2974 ? target()->FindFirstMap() 3086 ? target()->FindFirstMap()
2975 : HeapObject::cast(*object)->map()); 3087 : HeapObject::cast(*object)->map());
2976 code = isolate()->stub_cache()->ComputeCompareNil(monomorphic_map, stub); 3088 code = isolate()->stub_cache()->ComputeCompareNil(monomorphic_map, stub);
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after
3024 #undef ADDR 3136 #undef ADDR
3025 }; 3137 };
3026 3138
3027 3139
3028 Address IC::AddressFromUtilityId(IC::UtilityId id) { 3140 Address IC::AddressFromUtilityId(IC::UtilityId id) {
3029 return IC_utilities[id]; 3141 return IC_utilities[id];
3030 } 3142 }
3031 3143
3032 3144
3033 } } // namespace v8::internal 3145 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « src/ic.h ('k') | src/incremental-marking.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698