OLD | NEW |
1 // Copyright 2013 the V8 project authors. All rights reserved. | 1 // Copyright 2013 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 2060 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2071 | 2071 |
2072 HInstruction* HGraphBuilder::BuildUncheckedMonomorphicElementAccess( | 2072 HInstruction* HGraphBuilder::BuildUncheckedMonomorphicElementAccess( |
2073 HValue* checked_object, | 2073 HValue* checked_object, |
2074 HValue* key, | 2074 HValue* key, |
2075 HValue* val, | 2075 HValue* val, |
2076 bool is_js_array, | 2076 bool is_js_array, |
2077 ElementsKind elements_kind, | 2077 ElementsKind elements_kind, |
2078 bool is_store, | 2078 bool is_store, |
2079 LoadKeyedHoleMode load_mode, | 2079 LoadKeyedHoleMode load_mode, |
2080 KeyedAccessStoreMode store_mode) { | 2080 KeyedAccessStoreMode store_mode) { |
2081 ASSERT((!IsExternalArrayElementsKind(elements_kind) && | 2081 ASSERT(!IsExternalArrayElementsKind(elements_kind) || !is_js_array); |
2082 !IsFixedTypedArrayElementsKind(elements_kind)) || | |
2083 !is_js_array); | |
2084 // No GVNFlag is necessary for ElementsKind if there is an explicit dependency | 2082 // No GVNFlag is necessary for ElementsKind if there is an explicit dependency |
2085 // on a HElementsTransition instruction. The flag can also be removed if the | 2083 // on a HElementsTransition instruction. The flag can also be removed if the |
2086 // map to check has FAST_HOLEY_ELEMENTS, since there can be no further | 2084 // map to check has FAST_HOLEY_ELEMENTS, since there can be no further |
2087 // ElementsKind transitions. Finally, the dependency can be removed for stores | 2085 // ElementsKind transitions. Finally, the dependency can be removed for stores |
2088 // for FAST_ELEMENTS, since a transition to HOLEY elements won't change the | 2086 // for FAST_ELEMENTS, since a transition to HOLEY elements won't change the |
2089 // generated store code. | 2087 // generated store code. |
2090 if ((elements_kind == FAST_HOLEY_ELEMENTS) || | 2088 if ((elements_kind == FAST_HOLEY_ELEMENTS) || |
2091 (elements_kind == FAST_ELEMENTS && is_store)) { | 2089 (elements_kind == FAST_ELEMENTS && is_store)) { |
2092 checked_object->ClearGVNFlag(kDependsOnElementsKind); | 2090 checked_object->ClearGVNFlag(kDependsOnElementsKind); |
2093 } | 2091 } |
2094 | 2092 |
2095 bool fast_smi_only_elements = IsFastSmiElementsKind(elements_kind); | 2093 bool fast_smi_only_elements = IsFastSmiElementsKind(elements_kind); |
2096 bool fast_elements = IsFastObjectElementsKind(elements_kind); | 2094 bool fast_elements = IsFastObjectElementsKind(elements_kind); |
2097 HValue* elements = AddLoadElements(checked_object); | 2095 HValue* elements = AddLoadElements(checked_object); |
2098 if (is_store && (fast_elements || fast_smi_only_elements) && | 2096 if (is_store && (fast_elements || fast_smi_only_elements) && |
2099 store_mode != STORE_NO_TRANSITION_HANDLE_COW) { | 2097 store_mode != STORE_NO_TRANSITION_HANDLE_COW) { |
2100 HCheckMaps* check_cow_map = Add<HCheckMaps>( | 2098 HCheckMaps* check_cow_map = Add<HCheckMaps>( |
2101 elements, isolate()->factory()->fixed_array_map(), top_info()); | 2099 elements, isolate()->factory()->fixed_array_map(), top_info()); |
2102 check_cow_map->ClearGVNFlag(kDependsOnElementsKind); | 2100 check_cow_map->ClearGVNFlag(kDependsOnElementsKind); |
2103 } | 2101 } |
2104 HInstruction* length = NULL; | 2102 HInstruction* length = NULL; |
2105 if (is_js_array) { | 2103 if (is_js_array) { |
2106 length = Add<HLoadNamedField>( | 2104 length = Add<HLoadNamedField>( |
2107 checked_object, HObjectAccess::ForArrayLength(elements_kind)); | 2105 checked_object, HObjectAccess::ForArrayLength(elements_kind)); |
2108 } else { | 2106 } else { |
2109 length = AddLoadFixedArrayLength(elements); | 2107 length = AddLoadFixedArrayLength(elements); |
2110 } | 2108 } |
2111 length->set_type(HType::Smi()); | 2109 length->set_type(HType::Smi()); |
2112 HValue* checked_key = NULL; | 2110 HValue* checked_key = NULL; |
2113 if (IsExternalArrayElementsKind(elements_kind) || | 2111 if (IsExternalArrayElementsKind(elements_kind)) { |
2114 IsFixedTypedArrayElementsKind(elements_kind)) { | |
2115 HValue* backing_store; | |
2116 if (IsExternalArrayElementsKind(elements_kind)) { | |
2117 backing_store = | |
2118 Add<HLoadExternalArrayPointer>(elements); | |
2119 } else { | |
2120 backing_store = elements; | |
2121 } | |
2122 if (store_mode == STORE_NO_TRANSITION_IGNORE_OUT_OF_BOUNDS) { | 2112 if (store_mode == STORE_NO_TRANSITION_IGNORE_OUT_OF_BOUNDS) { |
2123 NoObservableSideEffectsScope no_effects(this); | 2113 NoObservableSideEffectsScope no_effects(this); |
| 2114 HLoadExternalArrayPointer* external_elements = |
| 2115 Add<HLoadExternalArrayPointer>(elements); |
2124 IfBuilder length_checker(this); | 2116 IfBuilder length_checker(this); |
2125 length_checker.If<HCompareNumericAndBranch>(key, length, Token::LT); | 2117 length_checker.If<HCompareNumericAndBranch>(key, length, Token::LT); |
2126 length_checker.Then(); | 2118 length_checker.Then(); |
2127 IfBuilder negative_checker(this); | 2119 IfBuilder negative_checker(this); |
2128 HValue* bounds_check = negative_checker.If<HCompareNumericAndBranch>( | 2120 HValue* bounds_check = negative_checker.If<HCompareNumericAndBranch>( |
2129 key, graph()->GetConstant0(), Token::GTE); | 2121 key, graph()->GetConstant0(), Token::GTE); |
2130 negative_checker.Then(); | 2122 negative_checker.Then(); |
2131 HInstruction* result = AddElementAccess( | 2123 HInstruction* result = AddElementAccess( |
2132 backing_store, key, val, bounds_check, elements_kind, is_store); | 2124 external_elements, key, val, bounds_check, elements_kind, is_store); |
2133 negative_checker.ElseDeopt("Negative key encountered"); | 2125 negative_checker.ElseDeopt("Negative key encountered"); |
2134 negative_checker.End(); | 2126 negative_checker.End(); |
2135 length_checker.End(); | 2127 length_checker.End(); |
2136 return result; | 2128 return result; |
2137 } else { | 2129 } else { |
2138 ASSERT(store_mode == STANDARD_STORE); | 2130 ASSERT(store_mode == STANDARD_STORE); |
2139 checked_key = Add<HBoundsCheck>(key, length); | 2131 checked_key = Add<HBoundsCheck>(key, length); |
| 2132 HLoadExternalArrayPointer* external_elements = |
| 2133 Add<HLoadExternalArrayPointer>(elements); |
2140 return AddElementAccess( | 2134 return AddElementAccess( |
2141 backing_store, checked_key, val, | 2135 external_elements, checked_key, val, |
2142 checked_object, elements_kind, is_store); | 2136 checked_object, elements_kind, is_store); |
2143 } | 2137 } |
2144 } | 2138 } |
2145 ASSERT(fast_smi_only_elements || | 2139 ASSERT(fast_smi_only_elements || |
2146 fast_elements || | 2140 fast_elements || |
2147 IsFastDoubleElementsKind(elements_kind)); | 2141 IsFastDoubleElementsKind(elements_kind)); |
2148 | 2142 |
2149 // In case val is stored into a fast smi array, assure that the value is a smi | 2143 // In case val is stored into a fast smi array, assure that the value is a smi |
2150 // before manipulating the backing store. Otherwise the actual store may | 2144 // before manipulating the backing store. Otherwise the actual store may |
2151 // deopt, leaving the backing store in an invalid state. | 2145 // deopt, leaving the backing store in an invalid state. |
(...skipping 160 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2312 HInstruction* HGraphBuilder::AddElementAccess( | 2306 HInstruction* HGraphBuilder::AddElementAccess( |
2313 HValue* elements, | 2307 HValue* elements, |
2314 HValue* checked_key, | 2308 HValue* checked_key, |
2315 HValue* val, | 2309 HValue* val, |
2316 HValue* dependency, | 2310 HValue* dependency, |
2317 ElementsKind elements_kind, | 2311 ElementsKind elements_kind, |
2318 bool is_store, | 2312 bool is_store, |
2319 LoadKeyedHoleMode load_mode) { | 2313 LoadKeyedHoleMode load_mode) { |
2320 if (is_store) { | 2314 if (is_store) { |
2321 ASSERT(val != NULL); | 2315 ASSERT(val != NULL); |
2322 if (elements_kind == EXTERNAL_PIXEL_ELEMENTS || | 2316 if (elements_kind == EXTERNAL_PIXEL_ELEMENTS) { |
2323 elements_kind == UINT8_CLAMPED_ELEMENTS) { | |
2324 val = Add<HClampToUint8>(val); | 2317 val = Add<HClampToUint8>(val); |
2325 } | 2318 } |
2326 return Add<HStoreKeyed>(elements, checked_key, val, elements_kind, | 2319 return Add<HStoreKeyed>(elements, checked_key, val, elements_kind, |
2327 elements_kind == FAST_SMI_ELEMENTS | 2320 elements_kind == FAST_SMI_ELEMENTS |
2328 ? STORE_TO_INITIALIZED_ENTRY | 2321 ? STORE_TO_INITIALIZED_ENTRY |
2329 : INITIALIZING_STORE); | 2322 : INITIALIZING_STORE); |
2330 } | 2323 } |
2331 | 2324 |
2332 ASSERT(!is_store); | 2325 ASSERT(!is_store); |
2333 ASSERT(val == NULL); | 2326 ASSERT(val == NULL); |
2334 HLoadKeyed* load = Add<HLoadKeyed>( | 2327 HLoadKeyed* load = Add<HLoadKeyed>( |
2335 elements, checked_key, dependency, elements_kind, load_mode); | 2328 elements, checked_key, dependency, elements_kind, load_mode); |
2336 if (FLAG_opt_safe_uint32_operations && | 2329 if (FLAG_opt_safe_uint32_operations && |
2337 (elements_kind == EXTERNAL_UNSIGNED_INT_ELEMENTS || | 2330 elements_kind == EXTERNAL_UNSIGNED_INT_ELEMENTS) { |
2338 elements_kind == UINT32_ELEMENTS)) { | |
2339 graph()->RecordUint32Instruction(load); | 2331 graph()->RecordUint32Instruction(load); |
2340 } | 2332 } |
2341 return load; | 2333 return load; |
2342 } | 2334 } |
2343 | 2335 |
2344 | 2336 |
2345 HLoadNamedField* HGraphBuilder::AddLoadElements(HValue* object) { | 2337 HLoadNamedField* HGraphBuilder::AddLoadElements(HValue* object) { |
2346 return Add<HLoadNamedField>(object, HObjectAccess::ForElementsPointer()); | 2338 return Add<HLoadNamedField>(object, HObjectAccess::ForElementsPointer()); |
2347 } | 2339 } |
2348 | 2340 |
(...skipping 8654 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
11003 if (ShouldProduceTraceOutput()) { | 10995 if (ShouldProduceTraceOutput()) { |
11004 isolate()->GetHTracer()->TraceHydrogen(name(), graph_); | 10996 isolate()->GetHTracer()->TraceHydrogen(name(), graph_); |
11005 } | 10997 } |
11006 | 10998 |
11007 #ifdef DEBUG | 10999 #ifdef DEBUG |
11008 graph_->Verify(false); // No full verify. | 11000 graph_->Verify(false); // No full verify. |
11009 #endif | 11001 #endif |
11010 } | 11002 } |
11011 | 11003 |
11012 } } // namespace v8::internal | 11004 } } // namespace v8::internal |
OLD | NEW |