OLD | NEW |
1 // Copyright 2013 the V8 project authors. All rights reserved. | 1 // Copyright 2013 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 "hydrogen.h" | 5 #include "hydrogen.h" |
6 | 6 |
7 #include <algorithm> | 7 #include <algorithm> |
8 | 8 |
9 #include "v8.h" | 9 #include "v8.h" |
10 #include "allocation-site-scopes.h" | 10 #include "allocation-site-scopes.h" |
(...skipping 1542 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1553 HValue* elements = Add<HInnerAllocatedObject>( | 1553 HValue* elements = Add<HInnerAllocatedObject>( |
1554 result, Add<HConstant>(JSRegExpResult::kSize)); | 1554 result, Add<HConstant>(JSRegExpResult::kSize)); |
1555 | 1555 |
1556 // Initialize the JSRegExpResult header. | 1556 // Initialize the JSRegExpResult header. |
1557 HValue* global_object = Add<HLoadNamedField>( | 1557 HValue* global_object = Add<HLoadNamedField>( |
1558 context(), static_cast<HValue*>(NULL), | 1558 context(), static_cast<HValue*>(NULL), |
1559 HObjectAccess::ForContextSlot(Context::GLOBAL_OBJECT_INDEX)); | 1559 HObjectAccess::ForContextSlot(Context::GLOBAL_OBJECT_INDEX)); |
1560 HValue* native_context = Add<HLoadNamedField>( | 1560 HValue* native_context = Add<HLoadNamedField>( |
1561 global_object, static_cast<HValue*>(NULL), | 1561 global_object, static_cast<HValue*>(NULL), |
1562 HObjectAccess::ForGlobalObjectNativeContext()); | 1562 HObjectAccess::ForGlobalObjectNativeContext()); |
1563 AddStoreMapNoWriteBarrier(result, Add<HLoadNamedField>( | 1563 Add<HStoreNamedField>( |
| 1564 result, HObjectAccess::ForMap(), |
| 1565 Add<HLoadNamedField>( |
1564 native_context, static_cast<HValue*>(NULL), | 1566 native_context, static_cast<HValue*>(NULL), |
1565 HObjectAccess::ForContextSlot(Context::REGEXP_RESULT_MAP_INDEX))); | 1567 HObjectAccess::ForContextSlot(Context::REGEXP_RESULT_MAP_INDEX))); |
1566 Add<HStoreNamedField>( | 1568 Add<HStoreNamedField>( |
1567 result, HObjectAccess::ForJSArrayOffset(JSArray::kPropertiesOffset), | 1569 result, HObjectAccess::ForJSArrayOffset(JSArray::kPropertiesOffset), |
1568 Add<HConstant>(isolate()->factory()->empty_fixed_array())); | 1570 Add<HConstant>(isolate()->factory()->empty_fixed_array())); |
1569 Add<HStoreNamedField>( | 1571 Add<HStoreNamedField>( |
1570 result, HObjectAccess::ForJSArrayOffset(JSArray::kElementsOffset), | 1572 result, HObjectAccess::ForJSArrayOffset(JSArray::kElementsOffset), |
1571 elements); | 1573 elements); |
1572 Add<HStoreNamedField>( | 1574 Add<HStoreNamedField>( |
1573 result, HObjectAccess::ForJSArrayOffset(JSArray::kLengthOffset), length); | 1575 result, HObjectAccess::ForJSArrayOffset(JSArray::kLengthOffset), length); |
1574 | 1576 |
1575 // Initialize the additional fields. | 1577 // Initialize the additional fields. |
1576 Add<HStoreNamedField>( | 1578 Add<HStoreNamedField>( |
1577 result, HObjectAccess::ForJSArrayOffset(JSRegExpResult::kIndexOffset), | 1579 result, HObjectAccess::ForJSArrayOffset(JSRegExpResult::kIndexOffset), |
1578 index); | 1580 index); |
1579 Add<HStoreNamedField>( | 1581 Add<HStoreNamedField>( |
1580 result, HObjectAccess::ForJSArrayOffset(JSRegExpResult::kInputOffset), | 1582 result, HObjectAccess::ForJSArrayOffset(JSRegExpResult::kInputOffset), |
1581 input); | 1583 input); |
1582 | 1584 |
1583 // Initialize the elements header. | 1585 // Initialize the elements header. |
1584 AddStoreMapConstantNoWriteBarrier(elements, | 1586 AddStoreMapConstant(elements, isolate()->factory()->fixed_array_map()); |
1585 isolate()->factory()->fixed_array_map()); | |
1586 Add<HStoreNamedField>(elements, HObjectAccess::ForFixedArrayLength(), length); | 1587 Add<HStoreNamedField>(elements, HObjectAccess::ForFixedArrayLength(), length); |
1587 | 1588 |
1588 // Initialize the elements contents with undefined. | 1589 // Initialize the elements contents with undefined. |
1589 LoopBuilder loop(this, context(), LoopBuilder::kPostIncrement); | 1590 LoopBuilder loop(this, context(), LoopBuilder::kPostIncrement); |
1590 index = loop.BeginBody(graph()->GetConstant0(), length, Token::LT); | 1591 index = loop.BeginBody(graph()->GetConstant0(), length, Token::LT); |
1591 { | 1592 { |
1592 Add<HStoreKeyed>(elements, index, graph()->GetConstantUndefined(), | 1593 Add<HStoreKeyed>(elements, index, graph()->GetConstantUndefined(), |
1593 FAST_ELEMENTS); | 1594 FAST_ELEMENTS); |
1594 } | 1595 } |
1595 loop.EndBody(); | 1596 loop.EndBody(); |
(...skipping 229 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1825 if_onebyte.If<HCompareNumericAndBranch>( | 1826 if_onebyte.If<HCompareNumericAndBranch>( |
1826 AddUncasted<HBitwise>( | 1827 AddUncasted<HBitwise>( |
1827 Token::BIT_AND, xored_instance_types, | 1828 Token::BIT_AND, xored_instance_types, |
1828 Add<HConstant>(static_cast<int32_t>( | 1829 Add<HConstant>(static_cast<int32_t>( |
1829 kOneByteStringTag | kOneByteDataHintTag))), | 1830 kOneByteStringTag | kOneByteDataHintTag))), |
1830 Add<HConstant>(static_cast<int32_t>( | 1831 Add<HConstant>(static_cast<int32_t>( |
1831 kOneByteStringTag | kOneByteDataHintTag)), Token::EQ); | 1832 kOneByteStringTag | kOneByteDataHintTag)), Token::EQ); |
1832 if_onebyte.Then(); | 1833 if_onebyte.Then(); |
1833 { | 1834 { |
1834 // We can safely skip the write barrier for storing the map here. | 1835 // We can safely skip the write barrier for storing the map here. |
1835 Handle<Map> map = isolate()->factory()->cons_ascii_string_map(); | 1836 Add<HStoreNamedField>( |
1836 AddStoreMapConstantNoWriteBarrier(result, map); | 1837 result, HObjectAccess::ForMap(), |
| 1838 Add<HConstant>(isolate()->factory()->cons_ascii_string_map())); |
1837 } | 1839 } |
1838 if_onebyte.Else(); | 1840 if_onebyte.Else(); |
1839 { | 1841 { |
1840 // We can safely skip the write barrier for storing the map here. | 1842 // We can safely skip the write barrier for storing the map here. |
1841 Handle<Map> map = isolate()->factory()->cons_string_map(); | 1843 Add<HStoreNamedField>( |
1842 AddStoreMapConstantNoWriteBarrier(result, map); | 1844 result, HObjectAccess::ForMap(), |
| 1845 Add<HConstant>(isolate()->factory()->cons_string_map())); |
1843 } | 1846 } |
1844 if_onebyte.End(); | 1847 if_onebyte.End(); |
1845 | 1848 |
1846 // Initialize the cons string fields. | 1849 // Initialize the cons string fields. |
1847 Add<HStoreNamedField>(result, HObjectAccess::ForStringHashField(), | 1850 Add<HStoreNamedField>(result, HObjectAccess::ForStringHashField(), |
1848 Add<HConstant>(String::kEmptyHashField)); | 1851 Add<HConstant>(String::kEmptyHashField)); |
1849 Add<HStoreNamedField>(result, HObjectAccess::ForStringLength(), length); | 1852 Add<HStoreNamedField>(result, HObjectAccess::ForStringLength(), length); |
1850 Add<HStoreNamedField>(result, HObjectAccess::ForConsStringFirst(), left); | 1853 Add<HStoreNamedField>(result, HObjectAccess::ForConsStringFirst(), left); |
1851 Add<HStoreNamedField>(result, HObjectAccess::ForConsStringSecond(), right); | 1854 Add<HStoreNamedField>(result, HObjectAccess::ForConsStringSecond(), right); |
1852 | 1855 |
(...skipping 138 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1991 | 1994 |
1992 // Calculate the number of bytes needed for the characters in the | 1995 // Calculate the number of bytes needed for the characters in the |
1993 // string while observing object alignment. | 1996 // string while observing object alignment. |
1994 STATIC_ASSERT((SeqString::kHeaderSize & kObjectAlignmentMask) == 0); | 1997 STATIC_ASSERT((SeqString::kHeaderSize & kObjectAlignmentMask) == 0); |
1995 HValue* size = BuildObjectSizeAlignment(Pop(), SeqString::kHeaderSize); | 1998 HValue* size = BuildObjectSizeAlignment(Pop(), SeqString::kHeaderSize); |
1996 | 1999 |
1997 // Allocate the string object. HAllocate does not care whether we pass | 2000 // Allocate the string object. HAllocate does not care whether we pass |
1998 // STRING_TYPE or ASCII_STRING_TYPE here, so we just use STRING_TYPE here. | 2001 // STRING_TYPE or ASCII_STRING_TYPE here, so we just use STRING_TYPE here. |
1999 HAllocate* result = BuildAllocate( | 2002 HAllocate* result = BuildAllocate( |
2000 size, HType::String(), STRING_TYPE, allocation_mode); | 2003 size, HType::String(), STRING_TYPE, allocation_mode); |
2001 | 2004 Add<HStoreNamedField>(result, HObjectAccess::ForMap(), map); |
2002 // We can safely skip the write barrier for storing map here. | |
2003 AddStoreMapNoWriteBarrier(result, map); | |
2004 | 2005 |
2005 // Initialize the string fields. | 2006 // Initialize the string fields. |
2006 Add<HStoreNamedField>(result, HObjectAccess::ForStringHashField(), | 2007 Add<HStoreNamedField>(result, HObjectAccess::ForStringHashField(), |
2007 Add<HConstant>(String::kEmptyHashField)); | 2008 Add<HConstant>(String::kEmptyHashField)); |
2008 Add<HStoreNamedField>(result, HObjectAccess::ForStringLength(), length); | 2009 Add<HStoreNamedField>(result, HObjectAccess::ForStringLength(), length); |
2009 | 2010 |
2010 // Copy characters to the result string. | 2011 // Copy characters to the result string. |
2011 IfBuilder if_twobyte(this); | 2012 IfBuilder if_twobyte(this); |
2012 if_twobyte.If<HCompareObjectEqAndBranch>(map, string_map); | 2013 if_twobyte.If<HCompareObjectEqAndBranch>(map, string_map); |
2013 if_twobyte.Then(); | 2014 if_twobyte.Then(); |
(...skipping 286 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2300 | 2301 |
2301 | 2302 |
2302 void HGraphBuilder::BuildInitializeElementsHeader(HValue* elements, | 2303 void HGraphBuilder::BuildInitializeElementsHeader(HValue* elements, |
2303 ElementsKind kind, | 2304 ElementsKind kind, |
2304 HValue* capacity) { | 2305 HValue* capacity) { |
2305 Factory* factory = isolate()->factory(); | 2306 Factory* factory = isolate()->factory(); |
2306 Handle<Map> map = IsFastDoubleElementsKind(kind) | 2307 Handle<Map> map = IsFastDoubleElementsKind(kind) |
2307 ? factory->fixed_double_array_map() | 2308 ? factory->fixed_double_array_map() |
2308 : factory->fixed_array_map(); | 2309 : factory->fixed_array_map(); |
2309 | 2310 |
2310 AddStoreMapConstant(elements, map); | 2311 Add<HStoreNamedField>(elements, HObjectAccess::ForMap(), Add<HConstant>(map)); |
2311 Add<HStoreNamedField>(elements, HObjectAccess::ForFixedArrayLength(), | 2312 Add<HStoreNamedField>(elements, HObjectAccess::ForFixedArrayLength(), |
2312 capacity); | 2313 capacity); |
2313 } | 2314 } |
2314 | 2315 |
2315 | 2316 |
2316 HValue* HGraphBuilder::BuildAllocateElementsAndInitializeElementsHeader( | 2317 HValue* HGraphBuilder::BuildAllocateElementsAndInitializeElementsHeader( |
2317 ElementsKind kind, | 2318 ElementsKind kind, |
2318 HValue* capacity) { | 2319 HValue* capacity) { |
2319 // The HForceRepresentation is to prevent possible deopt on int-smi | 2320 // The HForceRepresentation is to prevent possible deopt on int-smi |
2320 // conversion after allocation but before the new object fields are set. | 2321 // conversion after allocation but before the new object fields are set. |
(...skipping 484 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2805 if (FLAG_allocation_site_pretenuring) { | 2806 if (FLAG_allocation_site_pretenuring) { |
2806 HValue* memento_create_count = Add<HLoadNamedField>( | 2807 HValue* memento_create_count = Add<HLoadNamedField>( |
2807 allocation_site, static_cast<HValue*>(NULL), | 2808 allocation_site, static_cast<HValue*>(NULL), |
2808 HObjectAccess::ForAllocationSiteOffset( | 2809 HObjectAccess::ForAllocationSiteOffset( |
2809 AllocationSite::kPretenureCreateCountOffset)); | 2810 AllocationSite::kPretenureCreateCountOffset)); |
2810 memento_create_count = AddUncasted<HAdd>( | 2811 memento_create_count = AddUncasted<HAdd>( |
2811 memento_create_count, graph()->GetConstant1()); | 2812 memento_create_count, graph()->GetConstant1()); |
2812 // This smi value is reset to zero after every gc, overflow isn't a problem | 2813 // This smi value is reset to zero after every gc, overflow isn't a problem |
2813 // since the counter is bounded by the new space size. | 2814 // since the counter is bounded by the new space size. |
2814 memento_create_count->ClearFlag(HValue::kCanOverflow); | 2815 memento_create_count->ClearFlag(HValue::kCanOverflow); |
2815 HStoreNamedField* store = Add<HStoreNamedField>( | 2816 Add<HStoreNamedField>( |
2816 allocation_site, HObjectAccess::ForAllocationSiteOffset( | 2817 allocation_site, HObjectAccess::ForAllocationSiteOffset( |
2817 AllocationSite::kPretenureCreateCountOffset), memento_create_count); | 2818 AllocationSite::kPretenureCreateCountOffset), memento_create_count); |
2818 // No write barrier needed to store a smi. | |
2819 store->SkipWriteBarrier(); | |
2820 } | 2819 } |
2821 } | 2820 } |
2822 | 2821 |
2823 | 2822 |
2824 HInstruction* HGraphBuilder::BuildGetNativeContext(HValue* closure) { | 2823 HInstruction* HGraphBuilder::BuildGetNativeContext(HValue* closure) { |
2825 // Get the global context, then the native context | 2824 // Get the global context, then the native context |
2826 HInstruction* context = | 2825 HInstruction* context = |
2827 Add<HLoadNamedField>(closure, static_cast<HValue*>(NULL), | 2826 Add<HLoadNamedField>(closure, static_cast<HValue*>(NULL), |
2828 HObjectAccess::ForFunctionContextPointer()); | 2827 HObjectAccess::ForFunctionContextPointer()); |
2829 HInstruction* global_object = Add<HLoadNamedField>( | 2828 HInstruction* global_object = Add<HLoadNamedField>( |
(...skipping 197 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3027 | 3026 |
3028 if (fill_mode == FILL_WITH_HOLE) { | 3027 if (fill_mode == FILL_WITH_HOLE) { |
3029 builder()->BuildFillElementsWithHole(elements_location_, kind_, | 3028 builder()->BuildFillElementsWithHole(elements_location_, kind_, |
3030 graph()->GetConstant0(), capacity); | 3029 graph()->GetConstant0(), capacity); |
3031 } | 3030 } |
3032 | 3031 |
3033 return new_object; | 3032 return new_object; |
3034 } | 3033 } |
3035 | 3034 |
3036 | 3035 |
3037 HStoreNamedField* HGraphBuilder::AddStoreMapConstant(HValue *object, | |
3038 Handle<Map> map) { | |
3039 return Add<HStoreNamedField>(object, HObjectAccess::ForMap(), | |
3040 Add<HConstant>(map)); | |
3041 } | |
3042 | |
3043 | |
3044 HValue* HGraphBuilder::AddLoadJSBuiltin(Builtins::JavaScript builtin) { | 3036 HValue* HGraphBuilder::AddLoadJSBuiltin(Builtins::JavaScript builtin) { |
3045 HValue* global_object = Add<HLoadNamedField>( | 3037 HValue* global_object = Add<HLoadNamedField>( |
3046 context(), static_cast<HValue*>(NULL), | 3038 context(), static_cast<HValue*>(NULL), |
3047 HObjectAccess::ForContextSlot(Context::GLOBAL_OBJECT_INDEX)); | 3039 HObjectAccess::ForContextSlot(Context::GLOBAL_OBJECT_INDEX)); |
3048 HObjectAccess access = HObjectAccess::ForObservableJSObjectOffset( | 3040 HObjectAccess access = HObjectAccess::ForObservableJSObjectOffset( |
3049 GlobalObject::kBuiltinsOffset); | 3041 GlobalObject::kBuiltinsOffset); |
3050 HValue* builtins = Add<HLoadNamedField>( | 3042 HValue* builtins = Add<HLoadNamedField>( |
3051 global_object, static_cast<HValue*>(NULL), access); | 3043 global_object, static_cast<HValue*>(NULL), access); |
3052 HObjectAccess function_access = HObjectAccess::ForObservableJSObjectOffset( | 3044 HObjectAccess function_access = HObjectAccess::ForObservableJSObjectOffset( |
3053 JSBuiltinsObject::OffsetOfFunctionWithId(builtin)); | 3045 JSBuiltinsObject::OffsetOfFunctionWithId(builtin)); |
(...skipping 8762 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
11816 if (ShouldProduceTraceOutput()) { | 11808 if (ShouldProduceTraceOutput()) { |
11817 isolate()->GetHTracer()->TraceHydrogen(name(), graph_); | 11809 isolate()->GetHTracer()->TraceHydrogen(name(), graph_); |
11818 } | 11810 } |
11819 | 11811 |
11820 #ifdef DEBUG | 11812 #ifdef DEBUG |
11821 graph_->Verify(false); // No full verify. | 11813 graph_->Verify(false); // No full verify. |
11822 #endif | 11814 #endif |
11823 } | 11815 } |
11824 | 11816 |
11825 } } // namespace v8::internal | 11817 } } // namespace v8::internal |
OLD | NEW |