| 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 |