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

Side by Side Diff: src/ic/ic.cc

Issue 585983002: Fix TRACE_GENERIC_IC coverage (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Created 6 years, 3 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 | « no previous file | no next file » | 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 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "src/v8.h" 5 #include "src/v8.h"
6 6
7 #include "src/accessors.h" 7 #include "src/accessors.h"
8 #include "src/api.h" 8 #include "src/api.h"
9 #include "src/arguments.h" 9 #include "src/arguments.h"
10 #include "src/base/bits.h" 10 #include "src/base/bits.h"
(...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after
69 do { \ 69 do { \
70 if (FLAG_trace_ic) { \ 70 if (FLAG_trace_ic) { \
71 PrintF("[%s patching generic stub in ", type); \ 71 PrintF("[%s patching generic stub in ", type); \
72 JavaScriptFrame::PrintTop(isolate, stdout, false, true); \ 72 JavaScriptFrame::PrintTop(isolate, stdout, false, true); \
73 PrintF(" (%s)]\n", reason); \ 73 PrintF(" (%s)]\n", reason); \
74 } \ 74 } \
75 } while (false) 75 } while (false)
76 76
77 #else 77 #else
78 78
79 #define TRACE_GENERIC_IC(isolate, type, reason) 79 #define TRACE_GENERIC_IC(isolate, type, reason) \
80 do { \
81 if (FLAG_trace_ic) { \
82 PrintF("[%s patching generic stub in ", type); \
83 PrintF("(see below) (%s)]\n", reason); \
84 } \
85 } while (false)
80 86
81 #endif // DEBUG 87 #endif // DEBUG
82 88
83 89
84 void IC::TraceIC(const char* type, Handle<Object> name) { 90 void IC::TraceIC(const char* type, Handle<Object> name) {
85 if (FLAG_trace_ic) { 91 if (FLAG_trace_ic) {
86 Code* new_target = raw_target(); 92 Code* new_target = raw_target();
87 State new_state = new_target->ic_state(); 93 State new_state = new_target->ic_state();
88 TraceIC(type, name, state(), new_state); 94 TraceIC(type, name, state(), new_state);
89 } 95 }
(...skipping 1043 matching lines...) Expand 10 before | Expand all | Expand 10 after
1133 return PropertyICCompiler::ComputeKeyedLoadMonomorphic(receiver_map); 1139 return PropertyICCompiler::ComputeKeyedLoadMonomorphic(receiver_map);
1134 } 1140 }
1135 1141
1136 DCHECK(state() != GENERIC); 1142 DCHECK(state() != GENERIC);
1137 1143
1138 // Determine the list of receiver maps that this call site has seen, 1144 // Determine the list of receiver maps that this call site has seen,
1139 // adding the map that was just encountered. 1145 // adding the map that was just encountered.
1140 if (!AddOneReceiverMapIfMissing(&target_receiver_maps, receiver_map)) { 1146 if (!AddOneReceiverMapIfMissing(&target_receiver_maps, receiver_map)) {
1141 // If the miss wasn't due to an unseen map, a polymorphic stub 1147 // If the miss wasn't due to an unseen map, a polymorphic stub
1142 // won't help, use the generic stub. 1148 // won't help, use the generic stub.
1143 TRACE_GENERIC_IC(isolate(), "KeyedIC", "same map added twice"); 1149 TRACE_GENERIC_IC(isolate(), "KeyedLoadIC", "same map added twice");
1144 return generic_stub(); 1150 return generic_stub();
1145 } 1151 }
1146 1152
1147 // If the maximum number of receiver maps has been exceeded, use the generic 1153 // If the maximum number of receiver maps has been exceeded, use the generic
1148 // version of the IC. 1154 // version of the IC.
1149 if (target_receiver_maps.length() > kMaxKeyedPolymorphism) { 1155 if (target_receiver_maps.length() > kMaxKeyedPolymorphism) {
1150 TRACE_GENERIC_IC(isolate(), "KeyedIC", "max polymorph exceeded"); 1156 TRACE_GENERIC_IC(isolate(), "KeyedLoadIC", "max polymorph exceeded");
1151 return generic_stub(); 1157 return generic_stub();
1152 } 1158 }
1153 1159
1154 return PropertyICCompiler::ComputeKeyedLoadPolymorphic(&target_receiver_maps); 1160 return PropertyICCompiler::ComputeKeyedLoadPolymorphic(&target_receiver_maps);
1155 } 1161 }
1156 1162
1157 1163
1158 MaybeHandle<Object> KeyedLoadIC::Load(Handle<Object> object, 1164 MaybeHandle<Object> KeyedLoadIC::Load(Handle<Object> object,
1159 Handle<Object> key) { 1165 Handle<Object> key) {
1160 if (MigrateDeprecated(object)) { 1166 if (MigrateDeprecated(object)) {
(...skipping 203 matching lines...) Expand 10 before | Expand all | Expand 10 after
1364 void StoreIC::UpdateCaches(LookupIterator* lookup, Handle<Object> value, 1370 void StoreIC::UpdateCaches(LookupIterator* lookup, Handle<Object> value,
1365 JSReceiver::StoreFromKeyed store_mode) { 1371 JSReceiver::StoreFromKeyed store_mode) {
1366 if (state() == UNINITIALIZED) { 1372 if (state() == UNINITIALIZED) {
1367 // This is the first time we execute this inline cache. Set the target to 1373 // This is the first time we execute this inline cache. Set the target to
1368 // the pre monomorphic stub to delay setting the monomorphic state. 1374 // the pre monomorphic stub to delay setting the monomorphic state.
1369 set_target(*pre_monomorphic_stub()); 1375 set_target(*pre_monomorphic_stub());
1370 TRACE_IC("StoreIC", lookup->name()); 1376 TRACE_IC("StoreIC", lookup->name());
1371 return; 1377 return;
1372 } 1378 }
1373 1379
1374 Handle<Code> code = LookupForWrite(lookup, value, store_mode) 1380 bool use_ic = LookupForWrite(lookup, value, store_mode);
1375 ? ComputeHandler(lookup, value) 1381 if (!use_ic) {
1376 : slow_stub(); 1382 TRACE_GENERIC_IC(isolate(), "StoreIC", "LookupForWrite said 'false'");
1383 }
1384 Handle<Code> code = use_ic ? ComputeHandler(lookup, value) : slow_stub();
1377 1385
1378 PatchCache(lookup->name(), code); 1386 PatchCache(lookup->name(), code);
1379 TRACE_IC("StoreIC", lookup->name()); 1387 TRACE_IC("StoreIC", lookup->name());
1380 } 1388 }
1381 1389
1382 1390
1383 Handle<Code> StoreIC::CompileHandler(LookupIterator* lookup, 1391 Handle<Code> StoreIC::CompileHandler(LookupIterator* lookup,
1384 Handle<Object> value, 1392 Handle<Object> value,
1385 CacheHolderFlag cache_holder) { 1393 CacheHolderFlag cache_holder) {
1386 DCHECK_NE(LookupIterator::JSPROXY, lookup->state()); 1394 DCHECK_NE(LookupIterator::JSPROXY, lookup->state());
1387 1395
1388 // This is currently guaranteed by checks in StoreIC::Store. 1396 // This is currently guaranteed by checks in StoreIC::Store.
1389 Handle<JSObject> receiver = Handle<JSObject>::cast(lookup->GetReceiver()); 1397 Handle<JSObject> receiver = Handle<JSObject>::cast(lookup->GetReceiver());
1390 Handle<JSObject> holder = lookup->GetHolder<JSObject>(); 1398 Handle<JSObject> holder = lookup->GetHolder<JSObject>();
1391 DCHECK(!receiver->IsAccessCheckNeeded()); 1399 DCHECK(!receiver->IsAccessCheckNeeded());
1392 1400
1393 switch (lookup->state()) { 1401 switch (lookup->state()) {
1394 case LookupIterator::TRANSITION: { 1402 case LookupIterator::TRANSITION: {
1395 Handle<Map> transition = lookup->transition_map(); 1403 Handle<Map> transition = lookup->transition_map();
1396 // Currently not handled by CompileStoreTransition. 1404 // Currently not handled by CompileStoreTransition.
1397 if (!holder->HasFastProperties()) break; 1405 if (!holder->HasFastProperties()) {
1406 TRACE_GENERIC_IC(isolate(), "StoreIC", "transition from slow");
1407 break;
1408 }
1398 1409
1399 DCHECK(lookup->IsCacheableTransition()); 1410 DCHECK(lookup->IsCacheableTransition());
1400 NamedStoreHandlerCompiler compiler(isolate(), receiver_type(), holder); 1411 NamedStoreHandlerCompiler compiler(isolate(), receiver_type(), holder);
1401 return compiler.CompileStoreTransition(transition, lookup->name()); 1412 return compiler.CompileStoreTransition(transition, lookup->name());
1402 } 1413 }
1403 1414
1404 case LookupIterator::INTERCEPTOR: { 1415 case LookupIterator::INTERCEPTOR: {
1405 DCHECK(!holder->GetNamedInterceptor()->setter()->IsUndefined()); 1416 DCHECK(!holder->GetNamedInterceptor()->setter()->IsUndefined());
1406 NamedStoreHandlerCompiler compiler(isolate(), receiver_type(), holder); 1417 NamedStoreHandlerCompiler compiler(isolate(), receiver_type(), holder);
1407 return compiler.CompileStoreInterceptor(lookup->name()); 1418 return compiler.CompileStoreInterceptor(lookup->name());
1408 } 1419 }
1409 1420
1410 case LookupIterator::ACCESSOR: { 1421 case LookupIterator::ACCESSOR: {
1411 if (!holder->HasFastProperties()) break; 1422 if (!holder->HasFastProperties()) {
1423 TRACE_GENERIC_IC(isolate(), "StoreIC", "accessor on slow map");
1424 break;
1425 }
1412 Handle<Object> accessors = lookup->GetAccessors(); 1426 Handle<Object> accessors = lookup->GetAccessors();
1413 if (accessors->IsExecutableAccessorInfo()) { 1427 if (accessors->IsExecutableAccessorInfo()) {
1414 Handle<ExecutableAccessorInfo> info = 1428 Handle<ExecutableAccessorInfo> info =
1415 Handle<ExecutableAccessorInfo>::cast(accessors); 1429 Handle<ExecutableAccessorInfo>::cast(accessors);
1416 if (v8::ToCData<Address>(info->setter()) == 0) break; 1430 if (v8::ToCData<Address>(info->setter()) == 0) {
1431 TRACE_GENERIC_IC(isolate(), "StoreIC", "setter == 0");
1432 break;
1433 }
1417 if (!ExecutableAccessorInfo::IsCompatibleReceiverType( 1434 if (!ExecutableAccessorInfo::IsCompatibleReceiverType(
1418 isolate(), info, receiver_type())) { 1435 isolate(), info, receiver_type())) {
1436 TRACE_GENERIC_IC(isolate(), "StoreIC", "incompatible receiver type");
1419 break; 1437 break;
1420 } 1438 }
1421 NamedStoreHandlerCompiler compiler(isolate(), receiver_type(), holder); 1439 NamedStoreHandlerCompiler compiler(isolate(), receiver_type(), holder);
1422 return compiler.CompileStoreCallback(receiver, lookup->name(), info); 1440 return compiler.CompileStoreCallback(receiver, lookup->name(), info);
1423 } else if (accessors->IsAccessorPair()) { 1441 } else if (accessors->IsAccessorPair()) {
1424 Handle<Object> setter(Handle<AccessorPair>::cast(accessors)->setter(), 1442 Handle<Object> setter(Handle<AccessorPair>::cast(accessors)->setter(),
1425 isolate()); 1443 isolate());
1426 if (!setter->IsJSFunction()) break; 1444 if (!setter->IsJSFunction()) {
1445 TRACE_GENERIC_IC(isolate(), "StoreIC", "setter not a function");
1446 break;
1447 }
1427 Handle<JSFunction> function = Handle<JSFunction>::cast(setter); 1448 Handle<JSFunction> function = Handle<JSFunction>::cast(setter);
1428 CallOptimization call_optimization(function); 1449 CallOptimization call_optimization(function);
1429 NamedStoreHandlerCompiler compiler(isolate(), receiver_type(), holder); 1450 NamedStoreHandlerCompiler compiler(isolate(), receiver_type(), holder);
1430 if (call_optimization.is_simple_api_call() && 1451 if (call_optimization.is_simple_api_call() &&
1431 call_optimization.IsCompatibleReceiver(receiver, holder)) { 1452 call_optimization.IsCompatibleReceiver(receiver, holder)) {
1432 return compiler.CompileStoreCallback(receiver, lookup->name(), 1453 return compiler.CompileStoreCallback(receiver, lookup->name(),
1433 call_optimization); 1454 call_optimization);
1434 } 1455 }
1435 return compiler.CompileStoreViaSetter(receiver, lookup->name(), 1456 return compiler.CompileStoreViaSetter(receiver, lookup->name(),
1436 Handle<JSFunction>::cast(setter)); 1457 Handle<JSFunction>::cast(setter));
1437 } 1458 }
1438 // TODO(dcarney): Handle correctly. 1459 // TODO(dcarney): Handle correctly.
1439 DCHECK(accessors->IsDeclaredAccessorInfo()); 1460 DCHECK(accessors->IsDeclaredAccessorInfo());
1461 TRACE_GENERIC_IC(isolate(), "StoreIC", "declared accessor info");
1440 break; 1462 break;
1441 } 1463 }
1442 1464
1443 case LookupIterator::DATA: { 1465 case LookupIterator::DATA: {
1444 if (lookup->is_dictionary_holder()) { 1466 if (lookup->is_dictionary_holder()) {
1445 if (holder->IsGlobalObject()) { 1467 if (holder->IsGlobalObject()) {
1446 Handle<PropertyCell> cell = lookup->GetPropertyCell(); 1468 Handle<PropertyCell> cell = lookup->GetPropertyCell();
1447 Handle<HeapType> union_type = PropertyCell::UpdatedType(cell, value); 1469 Handle<HeapType> union_type = PropertyCell::UpdatedType(cell, value);
1448 StoreGlobalStub stub(isolate(), union_type->IsConstant(), 1470 StoreGlobalStub stub(isolate(), union_type->IsConstant(),
1449 receiver->IsJSGlobalProxy()); 1471 receiver->IsJSGlobalProxy());
(...skipping 20 matching lines...) Expand all
1470 StoreFieldStub stub(isolate(), lookup->GetFieldIndex(), 1492 StoreFieldStub stub(isolate(), lookup->GetFieldIndex(),
1471 lookup->representation()); 1493 lookup->representation());
1472 return stub.GetCode(); 1494 return stub.GetCode();
1473 } 1495 }
1474 NamedStoreHandlerCompiler compiler(isolate(), receiver_type(), holder); 1496 NamedStoreHandlerCompiler compiler(isolate(), receiver_type(), holder);
1475 return compiler.CompileStoreField(lookup); 1497 return compiler.CompileStoreField(lookup);
1476 } 1498 }
1477 1499
1478 // -------------- Constant properties -------------- 1500 // -------------- Constant properties --------------
1479 DCHECK(lookup->property_details().type() == CONSTANT); 1501 DCHECK(lookup->property_details().type() == CONSTANT);
1502 TRACE_GENERIC_IC(isolate(), "StoreIC", "constant property");
1480 break; 1503 break;
1481 } 1504 }
1482 1505
1483 case LookupIterator::ACCESS_CHECK: 1506 case LookupIterator::ACCESS_CHECK:
1484 case LookupIterator::JSPROXY: 1507 case LookupIterator::JSPROXY:
1485 case LookupIterator::NOT_FOUND: 1508 case LookupIterator::NOT_FOUND:
1486 UNREACHABLE(); 1509 UNREACHABLE();
1487 } 1510 }
1488 return slow_stub(); 1511 return slow_stub();
1489 } 1512 }
1490 1513
1491 1514
1492 Handle<Code> KeyedStoreIC::StoreElementStub(Handle<JSObject> receiver, 1515 Handle<Code> KeyedStoreIC::StoreElementStub(Handle<JSObject> receiver,
1493 KeyedAccessStoreMode store_mode) { 1516 KeyedAccessStoreMode store_mode) {
1494 // Don't handle megamorphic property accesses for INTERCEPTORS or CALLBACKS 1517 // Don't handle megamorphic property accesses for INTERCEPTORS or CALLBACKS
1495 // via megamorphic stubs, since they don't have a map in their relocation info 1518 // via megamorphic stubs, since they don't have a map in their relocation info
1496 // and so the stubs can't be harvested for the object needed for a map check. 1519 // and so the stubs can't be harvested for the object needed for a map check.
1497 if (target()->type() != Code::NORMAL) { 1520 if (target()->type() != Code::NORMAL) {
1498 TRACE_GENERIC_IC(isolate(), "KeyedIC", "non-NORMAL target type"); 1521 TRACE_GENERIC_IC(isolate(), "KeyedStoreIC", "non-NORMAL target type");
1499 return generic_stub(); 1522 return generic_stub();
1500 } 1523 }
1501 1524
1502 Handle<Map> receiver_map(receiver->map(), isolate()); 1525 Handle<Map> receiver_map(receiver->map(), isolate());
1503 MapHandleList target_receiver_maps; 1526 MapHandleList target_receiver_maps;
1504 TargetMaps(&target_receiver_maps); 1527 TargetMaps(&target_receiver_maps);
1505 if (target_receiver_maps.length() == 0) { 1528 if (target_receiver_maps.length() == 0) {
1506 Handle<Map> monomorphic_map = 1529 Handle<Map> monomorphic_map =
1507 ComputeTransitionedMap(receiver_map, store_mode); 1530 ComputeTransitionedMap(receiver_map, store_mode);
1508 store_mode = GetNonTransitioningStoreMode(store_mode); 1531 store_mode = GetNonTransitioningStoreMode(store_mode);
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after
1554 if (IsTransitionStoreMode(store_mode)) { 1577 if (IsTransitionStoreMode(store_mode)) {
1555 Handle<Map> transitioned_receiver_map = 1578 Handle<Map> transitioned_receiver_map =
1556 ComputeTransitionedMap(receiver_map, store_mode); 1579 ComputeTransitionedMap(receiver_map, store_mode);
1557 map_added |= AddOneReceiverMapIfMissing(&target_receiver_maps, 1580 map_added |= AddOneReceiverMapIfMissing(&target_receiver_maps,
1558 transitioned_receiver_map); 1581 transitioned_receiver_map);
1559 } 1582 }
1560 1583
1561 if (!map_added) { 1584 if (!map_added) {
1562 // If the miss wasn't due to an unseen map, a polymorphic stub 1585 // If the miss wasn't due to an unseen map, a polymorphic stub
1563 // won't help, use the generic stub. 1586 // won't help, use the generic stub.
1564 TRACE_GENERIC_IC(isolate(), "KeyedIC", "same map added twice"); 1587 TRACE_GENERIC_IC(isolate(), "KeyedStoreIC", "same map added twice");
1565 return generic_stub(); 1588 return generic_stub();
1566 } 1589 }
1567 1590
1568 // If the maximum number of receiver maps has been exceeded, use the generic 1591 // If the maximum number of receiver maps has been exceeded, use the generic
1569 // version of the IC. 1592 // version of the IC.
1570 if (target_receiver_maps.length() > kMaxKeyedPolymorphism) { 1593 if (target_receiver_maps.length() > kMaxKeyedPolymorphism) {
1571 TRACE_GENERIC_IC(isolate(), "KeyedIC", "max polymorph exceeded"); 1594 TRACE_GENERIC_IC(isolate(), "KeyedStoreIC", "max polymorph exceeded");
1572 return generic_stub(); 1595 return generic_stub();
1573 } 1596 }
1574 1597
1575 // Make sure all polymorphic handlers have the same store mode, otherwise the 1598 // Make sure all polymorphic handlers have the same store mode, otherwise the
1576 // generic stub must be used. 1599 // generic stub must be used.
1577 store_mode = GetNonTransitioningStoreMode(store_mode); 1600 store_mode = GetNonTransitioningStoreMode(store_mode);
1578 if (old_store_mode != STANDARD_STORE) { 1601 if (old_store_mode != STANDARD_STORE) {
1579 if (store_mode == STANDARD_STORE) { 1602 if (store_mode == STANDARD_STORE) {
1580 store_mode = old_store_mode; 1603 store_mode = old_store_mode;
1581 } else if (store_mode != old_store_mode) { 1604 } else if (store_mode != old_store_mode) {
1582 TRACE_GENERIC_IC(isolate(), "KeyedIC", "store mode mismatch"); 1605 TRACE_GENERIC_IC(isolate(), "KeyedStoreIC", "store mode mismatch");
1583 return generic_stub(); 1606 return generic_stub();
1584 } 1607 }
1585 } 1608 }
1586 1609
1587 // If the store mode isn't the standard mode, make sure that all polymorphic 1610 // If the store mode isn't the standard mode, make sure that all polymorphic
1588 // receivers are either external arrays, or all "normal" arrays. Otherwise, 1611 // receivers are either external arrays, or all "normal" arrays. Otherwise,
1589 // use the generic stub. 1612 // use the generic stub.
1590 if (store_mode != STANDARD_STORE) { 1613 if (store_mode != STANDARD_STORE) {
1591 int external_arrays = 0; 1614 int external_arrays = 0;
1592 for (int i = 0; i < target_receiver_maps.length(); ++i) { 1615 for (int i = 0; i < target_receiver_maps.length(); ++i) {
1593 if (target_receiver_maps[i]->has_external_array_elements() || 1616 if (target_receiver_maps[i]->has_external_array_elements() ||
1594 target_receiver_maps[i]->has_fixed_typed_array_elements()) { 1617 target_receiver_maps[i]->has_fixed_typed_array_elements()) {
1595 external_arrays++; 1618 external_arrays++;
1596 } 1619 }
1597 } 1620 }
1598 if (external_arrays != 0 && 1621 if (external_arrays != 0 &&
1599 external_arrays != target_receiver_maps.length()) { 1622 external_arrays != target_receiver_maps.length()) {
1600 TRACE_GENERIC_IC(isolate(), "KeyedIC", 1623 TRACE_GENERIC_IC(isolate(), "KeyedStoreIC",
1601 "unsupported combination of external and normal arrays"); 1624 "unsupported combination of external and normal arrays");
1602 return generic_stub(); 1625 return generic_stub();
1603 } 1626 }
1604 } 1627 }
1605 1628
1606 return PropertyICCompiler::ComputeKeyedStorePolymorphic( 1629 return PropertyICCompiler::ComputeKeyedStorePolymorphic(
1607 &target_receiver_maps, store_mode, strict_mode()); 1630 &target_receiver_maps, store_mode, strict_mode());
1608 } 1631 }
1609 1632
1610 1633
(...skipping 134 matching lines...) Expand 10 before | Expand all | Expand 10 after
1745 1768
1746 Handle<Object> store_handle; 1769 Handle<Object> store_handle;
1747 Handle<Code> stub = generic_stub(); 1770 Handle<Code> stub = generic_stub();
1748 1771
1749 if (key->IsInternalizedString()) { 1772 if (key->IsInternalizedString()) {
1750 ASSIGN_RETURN_ON_EXCEPTION( 1773 ASSIGN_RETURN_ON_EXCEPTION(
1751 isolate(), store_handle, 1774 isolate(), store_handle,
1752 StoreIC::Store(object, Handle<String>::cast(key), value, 1775 StoreIC::Store(object, Handle<String>::cast(key), value,
1753 JSReceiver::MAY_BE_STORE_FROM_KEYED), 1776 JSReceiver::MAY_BE_STORE_FROM_KEYED),
1754 Object); 1777 Object);
1755 TRACE_GENERIC_IC(isolate(), "KeyedStoreIC", "set generic"); 1778 if (!is_target_set()) {
1756 set_target(*stub); 1779 TRACE_GENERIC_IC(isolate(), "KeyedStoreIC",
1780 "unhandled internalized string key");
1781 TRACE_IC("StoreIC", key);
1782 set_target(*stub);
1783 }
1757 return store_handle; 1784 return store_handle;
1758 } 1785 }
1759 1786
1760 bool use_ic = 1787 bool use_ic =
1761 FLAG_use_ic && !object->IsStringWrapper() && 1788 FLAG_use_ic && !object->IsStringWrapper() &&
1762 !object->IsAccessCheckNeeded() && !object->IsJSGlobalProxy() && 1789 !object->IsAccessCheckNeeded() && !object->IsJSGlobalProxy() &&
1763 !(object->IsJSObject() && JSObject::cast(*object)->map()->is_observed()); 1790 !(object->IsJSObject() && JSObject::cast(*object)->map()->is_observed());
1764 if (use_ic && !object->IsSmi()) { 1791 if (use_ic && !object->IsSmi()) {
1765 // Don't use ICs for maps of the objects in Array's prototype chain. We 1792 // Don't use ICs for maps of the objects in Array's prototype chain. We
1766 // expect to be able to trap element sets to objects with those maps in 1793 // expect to be able to trap element sets to objects with those maps in
1767 // the runtime to enable optimization of element hole access. 1794 // the runtime to enable optimization of element hole access.
1768 Handle<HeapObject> heap_object = Handle<HeapObject>::cast(object); 1795 Handle<HeapObject> heap_object = Handle<HeapObject>::cast(object);
1769 if (heap_object->map()->IsMapInArrayPrototypeChain()) use_ic = false; 1796 if (heap_object->map()->IsMapInArrayPrototypeChain()) {
1797 TRACE_GENERIC_IC(isolate(), "KeyedStoreIC", "map in array prototype");
1798 use_ic = false;
1799 }
1770 } 1800 }
1771 1801
1772 if (use_ic) { 1802 if (use_ic) {
1773 DCHECK(!object->IsAccessCheckNeeded()); 1803 DCHECK(!object->IsAccessCheckNeeded());
1774 1804
1775 if (object->IsJSObject()) { 1805 if (object->IsJSObject()) {
1776 Handle<JSObject> receiver = Handle<JSObject>::cast(object); 1806 Handle<JSObject> receiver = Handle<JSObject>::cast(object);
1777 bool key_is_smi_like = !Object::ToSmi(isolate(), key).is_null(); 1807 bool key_is_smi_like = !Object::ToSmi(isolate(), key).is_null();
1778 if (receiver->elements()->map() == 1808 if (receiver->elements()->map() ==
1779 isolate()->heap()->sloppy_arguments_elements_map()) { 1809 isolate()->heap()->sloppy_arguments_elements_map()) {
1780 if (strict_mode() == SLOPPY) { 1810 if (strict_mode() == SLOPPY) {
1781 stub = sloppy_arguments_stub(); 1811 stub = sloppy_arguments_stub();
1812 } else {
1813 TRACE_GENERIC_IC(isolate(), "KeyedStoreIC", "arguments receiver");
1782 } 1814 }
1783 } else if (key_is_smi_like && 1815 } else if (key_is_smi_like &&
1784 !(target().is_identical_to(sloppy_arguments_stub()))) { 1816 !(target().is_identical_to(sloppy_arguments_stub()))) {
1785 // We should go generic if receiver isn't a dictionary, but our 1817 // We should go generic if receiver isn't a dictionary, but our
1786 // prototype chain does have dictionary elements. This ensures that 1818 // prototype chain does have dictionary elements. This ensures that
1787 // other non-dictionary receivers in the polymorphic case benefit 1819 // other non-dictionary receivers in the polymorphic case benefit
1788 // from fast path keyed stores. 1820 // from fast path keyed stores.
1789 if (!(receiver->map()->DictionaryElementsInPrototypeChainOnly())) { 1821 if (!(receiver->map()->DictionaryElementsInPrototypeChainOnly())) {
1790 KeyedAccessStoreMode store_mode = GetStoreMode(receiver, key, value); 1822 KeyedAccessStoreMode store_mode = GetStoreMode(receiver, key, value);
1791 stub = StoreElementStub(receiver, store_mode); 1823 stub = StoreElementStub(receiver, store_mode);
1824 } else {
1825 TRACE_GENERIC_IC(isolate(), "KeyedStoreIC", "dictionary prototype");
1792 } 1826 }
1827 } else {
1828 TRACE_GENERIC_IC(isolate(), "KeyedStoreIC", "non-smi-like key");
1793 } 1829 }
1830 } else {
1831 TRACE_GENERIC_IC(isolate(), "KeyedStoreIC", "non-JSObject receiver");
1794 } 1832 }
1795 } 1833 }
1796 1834
1797 if (store_handle.is_null()) { 1835 if (store_handle.is_null()) {
1798 ASSIGN_RETURN_ON_EXCEPTION( 1836 ASSIGN_RETURN_ON_EXCEPTION(
1799 isolate(), store_handle, 1837 isolate(), store_handle,
1800 Runtime::SetObjectProperty(isolate(), object, key, value, 1838 Runtime::SetObjectProperty(isolate(), object, key, value,
1801 strict_mode()), 1839 strict_mode()),
1802 Object); 1840 Object);
1803 } 1841 }
1804 1842
1805 DCHECK(!is_target_set()); 1843 DCHECK(!is_target_set());
1806 Code* generic = *generic_stub(); 1844 Code* generic = *generic_stub();
1807 if (*stub == generic) { 1845 if (*stub == generic) {
1808 TRACE_GENERIC_IC(isolate(), "KeyedStoreIC", "set generic"); 1846 TRACE_GENERIC_IC(isolate(), "KeyedStoreIC", "set generic");
1809 } 1847 }
1848 if (*stub == *slow_stub()) {
1849 TRACE_GENERIC_IC(isolate(), "KeyedStoreIC", "slow stub");
1850 }
1810 DCHECK(!stub.is_null()); 1851 DCHECK(!stub.is_null());
1811 set_target(*stub); 1852 set_target(*stub);
1812 TRACE_IC("StoreIC", key); 1853 TRACE_IC("StoreIC", key);
1813 1854
1814 return store_handle; 1855 return store_handle;
1815 } 1856 }
1816 1857
1817 1858
1818 bool CallIC::DoCustomHandler(Handle<Object> receiver, Handle<Object> function, 1859 bool CallIC::DoCustomHandler(Handle<Object> receiver, Handle<Object> function,
1819 Handle<TypeFeedbackVector> vector, 1860 Handle<TypeFeedbackVector> vector,
(...skipping 787 matching lines...) Expand 10 before | Expand all | Expand 10 after
2607 static const Address IC_utilities[] = { 2648 static const Address IC_utilities[] = {
2608 #define ADDR(name) FUNCTION_ADDR(name), 2649 #define ADDR(name) FUNCTION_ADDR(name),
2609 IC_UTIL_LIST(ADDR) NULL 2650 IC_UTIL_LIST(ADDR) NULL
2610 #undef ADDR 2651 #undef ADDR
2611 }; 2652 };
2612 2653
2613 2654
2614 Address IC::AddressFromUtilityId(IC::UtilityId id) { return IC_utilities[id]; } 2655 Address IC::AddressFromUtilityId(IC::UtilityId id) { return IC_utilities[id]; }
2615 } 2656 }
2616 } // namespace v8::internal 2657 } // namespace v8::internal
OLDNEW
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698