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

Side by Side Diff: src/ic.cc

Issue 9310117: Implement KeyedStoreICs to grow arrays on out-of-bound stores. (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Add missing WB stub Created 8 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/ic-inl.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 63 matching lines...) Expand 10 before | Expand all | Expand 10 after
74 Isolate* isolate = new_target->GetIsolate(); 74 Isolate* isolate = new_target->GetIsolate();
75 Code* apply_builtin = isolate->builtins()->builtin( 75 Code* apply_builtin = isolate->builtins()->builtin(
76 Builtins::kFunctionApply); 76 Builtins::kFunctionApply);
77 if (raw_frame->unchecked_code() == apply_builtin) { 77 if (raw_frame->unchecked_code() == apply_builtin) {
78 PrintF("apply from "); 78 PrintF("apply from ");
79 it.Advance(); 79 it.Advance();
80 raw_frame = it.frame(); 80 raw_frame = it.frame();
81 } 81 }
82 } 82 }
83 JavaScriptFrame::PrintTop(stdout, false, true); 83 JavaScriptFrame::PrintTop(stdout, false, true);
84 PrintF(" (%c->%c)", 84 bool new_can_grow =
85 Code::GetKeyedAccessGrowMode(new_target->extra_ic_state()) ==
86 ALLOW_JSARRAY_GROWTH;
87 PrintF(" (%c->%c%s)",
85 TransitionMarkFromState(old_state), 88 TransitionMarkFromState(old_state),
86 TransitionMarkFromState(new_state)); 89 TransitionMarkFromState(new_state),
90 new_can_grow ? ".GROW" : "");
87 name->Print(); 91 name->Print();
88 PrintF("]\n"); 92 PrintF("]\n");
89 } 93 }
90 } 94 }
91 95
92 #define TRACE_GENERIC_IC(type, reason) \ 96 #define TRACE_GENERIC_IC(type, reason) \
93 do { \ 97 do { \
94 if (FLAG_trace_ic) { \ 98 if (FLAG_trace_ic) { \
95 PrintF("[%s patching generic stub in ", type); \ 99 PrintF("[%s patching generic stub in ", type); \
96 JavaScriptFrame::PrintTop(stdout, false, true); \ 100 JavaScriptFrame::PrintTop(stdout, false, true); \
(...skipping 271 matching lines...) Expand 10 before | Expand all | Expand 10 after
368 372
369 void LoadIC::Clear(Address address, Code* target) { 373 void LoadIC::Clear(Address address, Code* target) {
370 if (target->ic_state() == UNINITIALIZED) return; 374 if (target->ic_state() == UNINITIALIZED) return;
371 SetTargetAtAddress(address, initialize_stub()); 375 SetTargetAtAddress(address, initialize_stub());
372 } 376 }
373 377
374 378
375 void StoreIC::Clear(Address address, Code* target) { 379 void StoreIC::Clear(Address address, Code* target) {
376 if (target->ic_state() == UNINITIALIZED) return; 380 if (target->ic_state() == UNINITIALIZED) return;
377 SetTargetAtAddress(address, 381 SetTargetAtAddress(address,
378 (target->extra_ic_state() == kStrictMode) 382 (Code::GetStrictMode(target->extra_ic_state()) == kStrictMode)
379 ? initialize_stub_strict() 383 ? initialize_stub_strict()
380 : initialize_stub()); 384 : initialize_stub());
381 } 385 }
382 386
383 387
384 void KeyedStoreIC::Clear(Address address, Code* target) { 388 void KeyedStoreIC::Clear(Address address, Code* target) {
385 if (target->ic_state() == UNINITIALIZED) return; 389 if (target->ic_state() == UNINITIALIZED) return;
386 SetTargetAtAddress(address, 390 SetTargetAtAddress(address,
387 (target->extra_ic_state() == kStrictMode) 391 (Code::GetStrictMode(target->extra_ic_state()) == kStrictMode)
388 ? initialize_stub_strict() 392 ? initialize_stub_strict()
389 : initialize_stub()); 393 : initialize_stub());
390 } 394 }
391 395
392 396
393 static bool HasInterceptorGetter(JSObject* object) { 397 static bool HasInterceptorGetter(JSObject* object) {
394 return !object->GetNamedInterceptor()->getter()->IsUndefined(); 398 return !object->GetNamedInterceptor()->getter()->IsUndefined();
395 } 399 }
396 400
397 401
(...skipping 591 matching lines...) Expand 10 before | Expand all | Expand 10 after
989 // GenerateMonomorphicCacheProbe. 993 // GenerateMonomorphicCacheProbe.
990 isolate()->stub_cache()->Set(*name, receiver->map(), *code); 994 isolate()->stub_cache()->Set(*name, receiver->map(), *code);
991 } 995 }
992 996
993 TRACE_IC("LoadIC", name, state, target()); 997 TRACE_IC("LoadIC", name, state, target());
994 } 998 }
995 999
996 1000
997 Handle<Code> KeyedLoadIC::GetElementStubWithoutMapCheck( 1001 Handle<Code> KeyedLoadIC::GetElementStubWithoutMapCheck(
998 bool is_js_array, 1002 bool is_js_array,
999 ElementsKind elements_kind) { 1003 ElementsKind elements_kind,
1004 KeyedAccessGrowMode grow_mode) {
1005 ASSERT(grow_mode == DO_NOT_ALLOW_JSARRAY_GROWTH);
1000 return KeyedLoadElementStub(elements_kind).GetCode(); 1006 return KeyedLoadElementStub(elements_kind).GetCode();
1001 } 1007 }
1002 1008
1003 1009
1004 Handle<Code> KeyedLoadIC::ComputePolymorphicStub( 1010 Handle<Code> KeyedLoadIC::ComputePolymorphicStub(
1005 MapHandleList* receiver_maps, 1011 MapHandleList* receiver_maps,
1006 StrictModeFlag strict_mode) { 1012 StrictModeFlag strict_mode,
1013 KeyedAccessGrowMode growth_mode) {
1007 CodeHandleList handler_ics(receiver_maps->length()); 1014 CodeHandleList handler_ics(receiver_maps->length());
1008 for (int i = 0; i < receiver_maps->length(); ++i) { 1015 for (int i = 0; i < receiver_maps->length(); ++i) {
1009 Handle<Map> receiver_map = receiver_maps->at(i); 1016 Handle<Map> receiver_map = receiver_maps->at(i);
1010 Handle<Code> cached_stub = ComputeMonomorphicStubWithoutMapCheck( 1017 Handle<Code> cached_stub = ComputeMonomorphicStubWithoutMapCheck(
1011 receiver_map, strict_mode); 1018 receiver_map, strict_mode, growth_mode);
1012 handler_ics.Add(cached_stub); 1019 handler_ics.Add(cached_stub);
1013 } 1020 }
1014 KeyedLoadStubCompiler compiler(isolate()); 1021 KeyedLoadStubCompiler compiler(isolate());
1015 Handle<Code> code = compiler.CompileLoadPolymorphic( 1022 Handle<Code> code = compiler.CompileLoadPolymorphic(
1016 receiver_maps, &handler_ics); 1023 receiver_maps, &handler_ics);
1017 isolate()->counters()->keyed_load_polymorphic_stubs()->Increment(); 1024 isolate()->counters()->keyed_load_polymorphic_stubs()->Increment();
1018 PROFILE(isolate(), 1025 PROFILE(isolate(),
1019 CodeCreateEvent(Logger::KEYED_LOAD_MEGAMORPHIC_IC_TAG, *code, 0)); 1026 CodeCreateEvent(Logger::KEYED_LOAD_MEGAMORPHIC_IC_TAG, *code, 0));
1020 return code; 1027 return code;
1021 } 1028 }
(...skipping 464 matching lines...) Expand 10 before | Expand all | Expand 10 after
1486 } 1493 }
1487 } 1494 }
1488 } 1495 }
1489 1496
1490 1497
1491 Handle<Code> KeyedIC::ComputeStub(Handle<JSObject> receiver, 1498 Handle<Code> KeyedIC::ComputeStub(Handle<JSObject> receiver,
1492 StubKind stub_kind, 1499 StubKind stub_kind,
1493 StrictModeFlag strict_mode, 1500 StrictModeFlag strict_mode,
1494 Handle<Code> generic_stub) { 1501 Handle<Code> generic_stub) {
1495 State ic_state = target()->ic_state(); 1502 State ic_state = target()->ic_state();
1503 KeyedAccessGrowMode grow_mode = IsGrowStubKind(stub_kind)
1504 ? ALLOW_JSARRAY_GROWTH
1505 : DO_NOT_ALLOW_JSARRAY_GROWTH;
1496 if ((ic_state == UNINITIALIZED || ic_state == PREMONOMORPHIC) && 1506 if ((ic_state == UNINITIALIZED || ic_state == PREMONOMORPHIC) &&
1497 !IsTransitionStubKind(stub_kind)) { 1507 !IsTransitionStubKind(stub_kind)) {
1498 return ComputeMonomorphicStub( 1508 return ComputeMonomorphicStub(
1499 receiver, stub_kind, strict_mode, generic_stub); 1509 receiver, stub_kind, strict_mode, generic_stub);
1500 } 1510 }
1501 ASSERT(target() != *generic_stub); 1511 ASSERT(target() != *generic_stub);
1502 1512
1503 // Don't handle megamorphic property accesses for INTERCEPTORS or CALLBACKS 1513 // Don't handle megamorphic property accesses for INTERCEPTORS or CALLBACKS
1504 // via megamorphic stubs, since they don't have a map in their relocation info 1514 // via megamorphic stubs, since they don't have a map in their relocation info
1505 // and so the stubs can't be harvested for the object needed for a map check. 1515 // and so the stubs can't be harvested for the object needed for a map check.
(...skipping 24 matching lines...) Expand all
1530 return generic_stub; 1540 return generic_stub;
1531 } 1541 }
1532 1542
1533 // If the maximum number of receiver maps has been exceeded, use the generic 1543 // If the maximum number of receiver maps has been exceeded, use the generic
1534 // version of the IC. 1544 // version of the IC.
1535 if (target_receiver_maps.length() > kMaxKeyedPolymorphism) { 1545 if (target_receiver_maps.length() > kMaxKeyedPolymorphism) {
1536 TRACE_GENERIC_IC("KeyedIC", "max polymorph exceeded"); 1546 TRACE_GENERIC_IC("KeyedIC", "max polymorph exceeded");
1537 return generic_stub; 1547 return generic_stub;
1538 } 1548 }
1539 1549
1550 if ((Code::GetKeyedAccessGrowMode(target()->extra_ic_state()) ==
1551 ALLOW_JSARRAY_GROWTH)) {
1552 grow_mode = ALLOW_JSARRAY_GROWTH;
1553 }
1554
1540 Handle<PolymorphicCodeCache> cache = 1555 Handle<PolymorphicCodeCache> cache =
1541 isolate()->factory()->polymorphic_code_cache(); 1556 isolate()->factory()->polymorphic_code_cache();
1542 Code::Flags flags = Code::ComputeFlags(kind(), MEGAMORPHIC, strict_mode); 1557 Code::ExtraICState extra_state = Code::ComputeExtraICState(grow_mode,
1558 strict_mode);
1559 Code::Flags flags = Code::ComputeFlags(kind(), MEGAMORPHIC, extra_state);
1543 Handle<Object> probe = cache->Lookup(&target_receiver_maps, flags); 1560 Handle<Object> probe = cache->Lookup(&target_receiver_maps, flags);
1544 if (probe->IsCode()) return Handle<Code>::cast(probe); 1561 if (probe->IsCode()) return Handle<Code>::cast(probe);
1545 1562
1546 Handle<Code> stub = 1563 Handle<Code> stub =
1547 ComputePolymorphicStub(&target_receiver_maps, strict_mode); 1564 ComputePolymorphicStub(&target_receiver_maps, strict_mode, grow_mode);
1548 PolymorphicCodeCache::Update(cache, &target_receiver_maps, flags, stub); 1565 PolymorphicCodeCache::Update(cache, &target_receiver_maps, flags, stub);
1549 return stub; 1566 return stub;
1550 } 1567 }
1551 1568
1552 1569
1553 Handle<Code> KeyedIC::ComputeMonomorphicStubWithoutMapCheck( 1570 Handle<Code> KeyedIC::ComputeMonomorphicStubWithoutMapCheck(
1554 Handle<Map> receiver_map, 1571 Handle<Map> receiver_map,
1555 StrictModeFlag strict_mode) { 1572 StrictModeFlag strict_mode,
1573 KeyedAccessGrowMode grow_mode) {
1556 if ((receiver_map->instance_type() & kNotStringTag) == 0) { 1574 if ((receiver_map->instance_type() & kNotStringTag) == 0) {
1557 ASSERT(!string_stub().is_null()); 1575 ASSERT(!string_stub().is_null());
1558 return string_stub(); 1576 return string_stub();
1559 } else { 1577 } else {
1560 ASSERT(receiver_map->has_dictionary_elements() || 1578 ASSERT(receiver_map->has_dictionary_elements() ||
1561 receiver_map->has_fast_elements() || 1579 receiver_map->has_fast_elements() ||
1562 receiver_map->has_fast_smi_only_elements() || 1580 receiver_map->has_fast_smi_only_elements() ||
1563 receiver_map->has_fast_double_elements() || 1581 receiver_map->has_fast_double_elements() ||
1564 receiver_map->has_external_array_elements()); 1582 receiver_map->has_external_array_elements());
1565 bool is_js_array = receiver_map->instance_type() == JS_ARRAY_TYPE; 1583 bool is_js_array = receiver_map->instance_type() == JS_ARRAY_TYPE;
1566 return GetElementStubWithoutMapCheck(is_js_array, 1584 return GetElementStubWithoutMapCheck(is_js_array,
1567 receiver_map->elements_kind()); 1585 receiver_map->elements_kind(),
1586 grow_mode);
1568 } 1587 }
1569 } 1588 }
1570 1589
1571 1590
1572 Handle<Code> KeyedIC::ComputeMonomorphicStub(Handle<JSObject> receiver, 1591 Handle<Code> KeyedIC::ComputeMonomorphicStub(Handle<JSObject> receiver,
1573 StubKind stub_kind, 1592 StubKind stub_kind,
1574 StrictModeFlag strict_mode, 1593 StrictModeFlag strict_mode,
1575 Handle<Code> generic_stub) { 1594 Handle<Code> generic_stub) {
1576 if (receiver->HasFastElements() || 1595 if (receiver->HasFastElements() ||
1577 receiver->HasFastSmiOnlyElements() || 1596 receiver->HasFastSmiOnlyElements() ||
1578 receiver->HasExternalArrayElements() || 1597 receiver->HasExternalArrayElements() ||
1579 receiver->HasFastDoubleElements() || 1598 receiver->HasFastDoubleElements() ||
1580 receiver->HasDictionaryElements()) { 1599 receiver->HasDictionaryElements()) {
1581 return isolate()->stub_cache()->ComputeKeyedLoadOrStoreElement( 1600 return isolate()->stub_cache()->ComputeKeyedLoadOrStoreElement(
1582 receiver, stub_kind, strict_mode); 1601 receiver, stub_kind, strict_mode);
1583 } else { 1602 } else {
1584 return generic_stub; 1603 return generic_stub;
1585 } 1604 }
1586 } 1605 }
1587 1606
1588 1607
1589 Handle<Map> KeyedIC::ComputeTransitionedMap(Handle<JSObject> receiver, 1608 Handle<Map> KeyedIC::ComputeTransitionedMap(Handle<JSObject> receiver,
1590 StubKind stub_kind) { 1609 StubKind stub_kind) {
1591 switch (stub_kind) { 1610 switch (stub_kind) {
1592 case KeyedIC::STORE_TRANSITION_SMI_TO_OBJECT: 1611 case KeyedIC::STORE_TRANSITION_SMI_TO_OBJECT:
1593 case KeyedIC::STORE_TRANSITION_DOUBLE_TO_OBJECT: 1612 case KeyedIC::STORE_TRANSITION_DOUBLE_TO_OBJECT:
1613 case KeyedIC::STORE_AND_GROW_TRANSITION_SMI_TO_OBJECT:
1614 case KeyedIC::STORE_AND_GROW_TRANSITION_DOUBLE_TO_OBJECT:
1594 return JSObject::GetElementsTransitionMap(receiver, FAST_ELEMENTS); 1615 return JSObject::GetElementsTransitionMap(receiver, FAST_ELEMENTS);
1595 break; 1616 break;
1596 case KeyedIC::STORE_TRANSITION_SMI_TO_DOUBLE: 1617 case KeyedIC::STORE_TRANSITION_SMI_TO_DOUBLE:
1618 case KeyedIC::STORE_AND_GROW_TRANSITION_SMI_TO_DOUBLE:
1597 return JSObject::GetElementsTransitionMap(receiver, FAST_DOUBLE_ELEMENTS); 1619 return JSObject::GetElementsTransitionMap(receiver, FAST_DOUBLE_ELEMENTS);
1598 break; 1620 break;
1599 default: 1621 default:
1600 UNREACHABLE(); 1622 UNREACHABLE();
1601 return Handle<Map>::null(); 1623 return Handle<Map>::null();
1602 } 1624 }
1603 } 1625 }
1604 1626
1605 1627
1606 Handle<Code> KeyedStoreIC::GetElementStubWithoutMapCheck( 1628 Handle<Code> KeyedStoreIC::GetElementStubWithoutMapCheck(
1607 bool is_js_array, 1629 bool is_js_array,
1608 ElementsKind elements_kind) { 1630 ElementsKind elements_kind,
1609 return KeyedStoreElementStub(is_js_array, elements_kind).GetCode(); 1631 KeyedAccessGrowMode grow_mode) {
1632 return KeyedStoreElementStub(is_js_array, elements_kind, grow_mode).GetCode();
1610 } 1633 }
1611 1634
1612 1635
1613 Handle<Code> KeyedStoreIC::ComputePolymorphicStub(MapHandleList* receiver_maps, 1636 Handle<Code> KeyedStoreIC::ComputePolymorphicStub(
1614 StrictModeFlag strict_mode) { 1637 MapHandleList* receiver_maps,
1638 StrictModeFlag strict_mode,
1639 KeyedAccessGrowMode grow_mode) {
1615 // Collect MONOMORPHIC stubs for all target_receiver_maps. 1640 // Collect MONOMORPHIC stubs for all target_receiver_maps.
1616 CodeHandleList handler_ics(receiver_maps->length()); 1641 CodeHandleList handler_ics(receiver_maps->length());
1617 MapHandleList transitioned_maps(receiver_maps->length()); 1642 MapHandleList transitioned_maps(receiver_maps->length());
1618 for (int i = 0; i < receiver_maps->length(); ++i) { 1643 for (int i = 0; i < receiver_maps->length(); ++i) {
1619 Handle<Map> receiver_map(receiver_maps->at(i)); 1644 Handle<Map> receiver_map(receiver_maps->at(i));
1620 Handle<Code> cached_stub; 1645 Handle<Code> cached_stub;
1621 Handle<Map> transitioned_map = 1646 Handle<Map> transitioned_map =
1622 receiver_map->FindTransitionedMap(receiver_maps); 1647 receiver_map->FindTransitionedMap(receiver_maps);
1623 if (!transitioned_map.is_null()) { 1648 if (!transitioned_map.is_null()) {
1624 cached_stub = ElementsTransitionAndStoreStub( 1649 cached_stub = ElementsTransitionAndStoreStub(
1625 receiver_map->elements_kind(), // original elements_kind 1650 receiver_map->elements_kind(), // original elements_kind
1626 transitioned_map->elements_kind(), 1651 transitioned_map->elements_kind(),
1627 receiver_map->instance_type() == JS_ARRAY_TYPE, // is_js_array 1652 receiver_map->instance_type() == JS_ARRAY_TYPE, // is_js_array
1628 strict_mode).GetCode(); 1653 strict_mode, grow_mode).GetCode();
1629 } else { 1654 } else {
1630 cached_stub = ComputeMonomorphicStubWithoutMapCheck(receiver_map, 1655 cached_stub = ComputeMonomorphicStubWithoutMapCheck(receiver_map,
1631 strict_mode); 1656 strict_mode,
1657 grow_mode);
1632 } 1658 }
1633 ASSERT(!cached_stub.is_null()); 1659 ASSERT(!cached_stub.is_null());
1634 handler_ics.Add(cached_stub); 1660 handler_ics.Add(cached_stub);
1635 transitioned_maps.Add(transitioned_map); 1661 transitioned_maps.Add(transitioned_map);
1636 } 1662 }
1637 KeyedStoreStubCompiler compiler(isolate(), strict_mode); 1663 KeyedStoreStubCompiler compiler(isolate(), strict_mode, grow_mode);
1638 Handle<Code> code = compiler.CompileStorePolymorphic( 1664 Handle<Code> code = compiler.CompileStorePolymorphic(
1639 receiver_maps, &handler_ics, &transitioned_maps); 1665 receiver_maps, &handler_ics, &transitioned_maps);
1640 isolate()->counters()->keyed_store_polymorphic_stubs()->Increment(); 1666 isolate()->counters()->keyed_store_polymorphic_stubs()->Increment();
1641 PROFILE(isolate(), 1667 PROFILE(isolate(),
1642 CodeCreateEvent(Logger::KEYED_STORE_MEGAMORPHIC_IC_TAG, *code, 0)); 1668 CodeCreateEvent(Logger::KEYED_STORE_MEGAMORPHIC_IC_TAG, *code, 0));
1643 return code; 1669 return code;
1644 } 1670 }
1645 1671
1646 1672
1673 KeyedIC::StubKind KeyedStoreIC::GetStubKind(Handle<JSObject> receiver,
1674 Handle<Object> key,
1675 Handle<Object> value) {
1676 ASSERT(key->IsSmi());
1677 int index = Smi::cast(*key)->value();
1678 bool allow_growth = receiver->IsJSArray() &&
1679 JSArray::cast(*receiver)->length()->IsSmi() &&
1680 index >= Smi::cast(JSArray::cast(*receiver)->length())->value();
1681
1682 if (allow_growth) {
1683 // Handle growing array in stub if necessary.
1684 if (receiver->HasFastSmiOnlyElements()) {
1685 if (value->IsHeapNumber()) {
1686 return STORE_AND_GROW_TRANSITION_SMI_TO_DOUBLE;
1687 }
1688 if (value->IsHeapObject()) {
1689 return STORE_AND_GROW_TRANSITION_SMI_TO_OBJECT;
1690 }
1691 } else if (receiver->HasFastDoubleElements()) {
1692 if (!value->IsSmi() && !value->IsHeapNumber()) {
1693 return STORE_AND_GROW_TRANSITION_DOUBLE_TO_OBJECT;
1694 }
1695 }
1696 return STORE_AND_GROW_NO_TRANSITION;
1697 } else {
1698 // Handle only in-bounds elements accesses.
1699 if (receiver->HasFastSmiOnlyElements()) {
1700 if (value->IsHeapNumber()) {
1701 return STORE_TRANSITION_SMI_TO_DOUBLE;
1702 } else if (value->IsHeapObject()) {
1703 return STORE_TRANSITION_SMI_TO_OBJECT;
1704 }
1705 } else if (receiver->HasFastDoubleElements()) {
1706 if (!value->IsSmi() && !value->IsHeapNumber()) {
1707 return STORE_TRANSITION_DOUBLE_TO_OBJECT;
1708 }
1709 }
1710 return STORE_NO_TRANSITION;
1711 }
1712 }
1713
1714
1647 MaybeObject* KeyedStoreIC::Store(State state, 1715 MaybeObject* KeyedStoreIC::Store(State state,
1648 StrictModeFlag strict_mode, 1716 StrictModeFlag strict_mode,
1649 Handle<Object> object, 1717 Handle<Object> object,
1650 Handle<Object> key, 1718 Handle<Object> key,
1651 Handle<Object> value, 1719 Handle<Object> value,
1652 bool force_generic) { 1720 bool force_generic) {
1653 if (key->IsSymbol()) { 1721 if (key->IsSymbol()) {
1654 Handle<String> name = Handle<String>::cast(key); 1722 Handle<String> name = Handle<String>::cast(key);
1655 1723
1656 // Handle proxies. 1724 // Handle proxies.
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after
1699 Handle<Code> stub = (strict_mode == kStrictMode) 1767 Handle<Code> stub = (strict_mode == kStrictMode)
1700 ? generic_stub_strict() 1768 ? generic_stub_strict()
1701 : generic_stub(); 1769 : generic_stub();
1702 if (object->IsJSObject()) { 1770 if (object->IsJSObject()) {
1703 Handle<JSObject> receiver = Handle<JSObject>::cast(object); 1771 Handle<JSObject> receiver = Handle<JSObject>::cast(object);
1704 if (receiver->elements()->map() == 1772 if (receiver->elements()->map() ==
1705 isolate()->heap()->non_strict_arguments_elements_map()) { 1773 isolate()->heap()->non_strict_arguments_elements_map()) {
1706 stub = non_strict_arguments_stub(); 1774 stub = non_strict_arguments_stub();
1707 } else if (!force_generic) { 1775 } else if (!force_generic) {
1708 if (key->IsSmi() && (target() != *non_strict_arguments_stub())) { 1776 if (key->IsSmi() && (target() != *non_strict_arguments_stub())) {
1709 StubKind stub_kind = STORE_NO_TRANSITION; 1777 StubKind stub_kind = GetStubKind(receiver, key, value);
1710 if (receiver->GetElementsKind() == FAST_SMI_ONLY_ELEMENTS) {
1711 if (value->IsHeapNumber()) {
1712 stub_kind = STORE_TRANSITION_SMI_TO_DOUBLE;
1713 } else if (value->IsHeapObject()) {
1714 stub_kind = STORE_TRANSITION_SMI_TO_OBJECT;
1715 }
1716 } else if (receiver->GetElementsKind() == FAST_DOUBLE_ELEMENTS) {
1717 if (!value->IsSmi() && !value->IsHeapNumber()) {
1718 stub_kind = STORE_TRANSITION_DOUBLE_TO_OBJECT;
1719 }
1720 }
1721 stub = ComputeStub(receiver, stub_kind, strict_mode, stub); 1778 stub = ComputeStub(receiver, stub_kind, strict_mode, stub);
1722 } 1779 }
1723 } else { 1780 } else {
1724 TRACE_GENERIC_IC("KeyedStoreIC", "force generic"); 1781 TRACE_GENERIC_IC("KeyedStoreIC", "force generic");
1725 } 1782 }
1726 } 1783 }
1727 if (!stub.is_null()) set_target(*stub); 1784 if (!stub.is_null()) set_target(*stub);
1728 } 1785 }
1729 1786
1730 TRACE_IC("KeyedStoreIC", key, state, target()); 1787 TRACE_IC("KeyedStoreIC", key, state, target());
(...skipping 162 matching lines...) Expand 10 before | Expand all | Expand 10 after
1893 1950
1894 1951
1895 // Used from ic-<arch>.cc. 1952 // Used from ic-<arch>.cc.
1896 RUNTIME_FUNCTION(MaybeObject*, StoreIC_Miss) { 1953 RUNTIME_FUNCTION(MaybeObject*, StoreIC_Miss) {
1897 HandleScope scope; 1954 HandleScope scope;
1898 ASSERT(args.length() == 3); 1955 ASSERT(args.length() == 3);
1899 StoreIC ic(isolate); 1956 StoreIC ic(isolate);
1900 IC::State state = IC::StateFrom(ic.target(), args[0], args[1]); 1957 IC::State state = IC::StateFrom(ic.target(), args[0], args[1]);
1901 Code::ExtraICState extra_ic_state = ic.target()->extra_ic_state(); 1958 Code::ExtraICState extra_ic_state = ic.target()->extra_ic_state();
1902 return ic.Store(state, 1959 return ic.Store(state,
1903 static_cast<StrictModeFlag>(extra_ic_state & kStrictMode), 1960 Code::GetStrictMode(extra_ic_state),
1904 args.at<Object>(0), 1961 args.at<Object>(0),
1905 args.at<String>(1), 1962 args.at<String>(1),
1906 args.at<Object>(2)); 1963 args.at<Object>(2));
1907 } 1964 }
1908 1965
1909 1966
1910 RUNTIME_FUNCTION(MaybeObject*, StoreIC_ArrayLength) { 1967 RUNTIME_FUNCTION(MaybeObject*, StoreIC_ArrayLength) {
1911 NoHandleAllocation nha; 1968 NoHandleAllocation nha;
1912 1969
1913 ASSERT(args.length() == 2); 1970 ASSERT(args.length() == 2);
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after
1969 2026
1970 2027
1971 // Used from ic-<arch>.cc. 2028 // Used from ic-<arch>.cc.
1972 RUNTIME_FUNCTION(MaybeObject*, KeyedStoreIC_Miss) { 2029 RUNTIME_FUNCTION(MaybeObject*, KeyedStoreIC_Miss) {
1973 HandleScope scope(isolate); 2030 HandleScope scope(isolate);
1974 ASSERT(args.length() == 3); 2031 ASSERT(args.length() == 3);
1975 KeyedStoreIC ic(isolate); 2032 KeyedStoreIC ic(isolate);
1976 IC::State state = IC::StateFrom(ic.target(), args[0], args[1]); 2033 IC::State state = IC::StateFrom(ic.target(), args[0], args[1]);
1977 Code::ExtraICState extra_ic_state = ic.target()->extra_ic_state(); 2034 Code::ExtraICState extra_ic_state = ic.target()->extra_ic_state();
1978 return ic.Store(state, 2035 return ic.Store(state,
1979 static_cast<StrictModeFlag>(extra_ic_state & kStrictMode), 2036 Code::GetStrictMode(extra_ic_state),
1980 args.at<Object>(0), 2037 args.at<Object>(0),
1981 args.at<Object>(1), 2038 args.at<Object>(1),
1982 args.at<Object>(2), 2039 args.at<Object>(2),
1983 false); 2040 false);
1984 } 2041 }
1985 2042
1986 2043
1987 RUNTIME_FUNCTION(MaybeObject*, KeyedStoreIC_Slow) { 2044 RUNTIME_FUNCTION(MaybeObject*, KeyedStoreIC_Slow) {
1988 NoHandleAllocation na; 2045 NoHandleAllocation na;
1989 ASSERT(args.length() == 3); 2046 ASSERT(args.length() == 3);
1990 KeyedStoreIC ic(isolate); 2047 KeyedStoreIC ic(isolate);
1991 Code::ExtraICState extra_ic_state = ic.target()->extra_ic_state(); 2048 Code::ExtraICState extra_ic_state = ic.target()->extra_ic_state();
1992 Handle<Object> object = args.at<Object>(0); 2049 Handle<Object> object = args.at<Object>(0);
1993 Handle<Object> key = args.at<Object>(1); 2050 Handle<Object> key = args.at<Object>(1);
1994 Handle<Object> value = args.at<Object>(2); 2051 Handle<Object> value = args.at<Object>(2);
1995 StrictModeFlag strict_mode = 2052 StrictModeFlag strict_mode = Code::GetStrictMode(extra_ic_state);
1996 static_cast<StrictModeFlag>(extra_ic_state & kStrictMode);
1997 return Runtime::SetObjectProperty(isolate, 2053 return Runtime::SetObjectProperty(isolate,
1998 object, 2054 object,
1999 key, 2055 key,
2000 value, 2056 value,
2001 NONE, 2057 NONE,
2002 strict_mode); 2058 strict_mode);
2003 } 2059 }
2004 2060
2005 2061
2006 RUNTIME_FUNCTION(MaybeObject*, KeyedStoreIC_MissForceGeneric) { 2062 RUNTIME_FUNCTION(MaybeObject*, KeyedStoreIC_MissForceGeneric) {
2007 HandleScope scope(isolate); 2063 HandleScope scope(isolate);
2008 ASSERT(args.length() == 3); 2064 ASSERT(args.length() == 3);
2009 KeyedStoreIC ic(isolate); 2065 KeyedStoreIC ic(isolate);
2010 IC::State state = IC::StateFrom(ic.target(), args[0], args[1]); 2066 IC::State state = IC::StateFrom(ic.target(), args[0], args[1]);
2011 Code::ExtraICState extra_ic_state = ic.target()->extra_ic_state(); 2067 Code::ExtraICState extra_ic_state = ic.target()->extra_ic_state();
2012 return ic.Store(state, 2068 return ic.Store(state,
2013 static_cast<StrictModeFlag>(extra_ic_state & kStrictMode), 2069 Code::GetStrictMode(extra_ic_state),
2014 args.at<Object>(0), 2070 args.at<Object>(0),
2015 args.at<Object>(1), 2071 args.at<Object>(1),
2016 args.at<Object>(2), 2072 args.at<Object>(2),
2017 true); 2073 true);
2018 } 2074 }
2019 2075
2020 2076
2021 void UnaryOpIC::patch(Code* code) { 2077 void UnaryOpIC::patch(Code* code) {
2022 set_target(code); 2078 set_target(code);
2023 } 2079 }
(...skipping 428 matching lines...) Expand 10 before | Expand all | Expand 10 after
2452 #undef ADDR 2508 #undef ADDR
2453 }; 2509 };
2454 2510
2455 2511
2456 Address IC::AddressFromUtilityId(IC::UtilityId id) { 2512 Address IC::AddressFromUtilityId(IC::UtilityId id) {
2457 return IC_utilities[id]; 2513 return IC_utilities[id];
2458 } 2514 }
2459 2515
2460 2516
2461 } } // namespace v8::internal 2517 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « src/ic.h ('k') | src/ic-inl.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698