| 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 "src/crankshaft/hydrogen.h" | 5 #include "src/crankshaft/hydrogen.h" |
| 6 | 6 |
| 7 #include <sstream> | 7 #include <sstream> |
| 8 | 8 |
| 9 #include "src/allocation-site-scopes.h" | 9 #include "src/allocation-site-scopes.h" |
| 10 #include "src/ast/ast-numbering.h" | 10 #include "src/ast/ast-numbering.h" |
| (...skipping 1088 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1099 void HGraphBuilder::IfBuilder::Else() { | 1099 void HGraphBuilder::IfBuilder::Else() { |
| 1100 DCHECK(did_then_); | 1100 DCHECK(did_then_); |
| 1101 DCHECK(!captured_); | 1101 DCHECK(!captured_); |
| 1102 DCHECK(!finished_); | 1102 DCHECK(!finished_); |
| 1103 AddMergeAtJoinBlock(false); | 1103 AddMergeAtJoinBlock(false); |
| 1104 builder()->set_current_block(first_false_block_); | 1104 builder()->set_current_block(first_false_block_); |
| 1105 pending_merge_block_ = true; | 1105 pending_merge_block_ = true; |
| 1106 did_else_ = true; | 1106 did_else_ = true; |
| 1107 } | 1107 } |
| 1108 | 1108 |
| 1109 | 1109 void HGraphBuilder::IfBuilder::Deopt(DeoptimizeReason reason) { |
| 1110 void HGraphBuilder::IfBuilder::Deopt(Deoptimizer::DeoptReason reason) { | |
| 1111 DCHECK(did_then_); | 1110 DCHECK(did_then_); |
| 1112 builder()->Add<HDeoptimize>(reason, Deoptimizer::EAGER); | 1111 builder()->Add<HDeoptimize>(reason, Deoptimizer::EAGER); |
| 1113 AddMergeAtJoinBlock(true); | 1112 AddMergeAtJoinBlock(true); |
| 1114 } | 1113 } |
| 1115 | 1114 |
| 1116 | 1115 |
| 1117 void HGraphBuilder::IfBuilder::Return(HValue* value) { | 1116 void HGraphBuilder::IfBuilder::Return(HValue* value) { |
| 1118 HValue* parameter_count = builder()->graph()->GetConstantMinus1(); | 1117 HValue* parameter_count = builder()->graph()->GetConstantMinus1(); |
| 1119 builder()->FinishExitCurrentBlock( | 1118 builder()->FinishExitCurrentBlock( |
| 1120 builder()->New<HReturn>(value, parameter_count)); | 1119 builder()->New<HReturn>(value, parameter_count)); |
| (...skipping 385 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1506 Add<HLoadNamedField>(map, nullptr, HObjectAccess::ForMapBitField3()); | 1505 Add<HLoadNamedField>(map, nullptr, HObjectAccess::ForMapBitField3()); |
| 1507 return BuildDecodeField<Map::EnumLengthBits>(bit_field3); | 1506 return BuildDecodeField<Map::EnumLengthBits>(bit_field3); |
| 1508 } | 1507 } |
| 1509 | 1508 |
| 1510 | 1509 |
| 1511 HValue* HGraphBuilder::BuildCheckHeapObject(HValue* obj) { | 1510 HValue* HGraphBuilder::BuildCheckHeapObject(HValue* obj) { |
| 1512 if (obj->type().IsHeapObject()) return obj; | 1511 if (obj->type().IsHeapObject()) return obj; |
| 1513 return Add<HCheckHeapObject>(obj); | 1512 return Add<HCheckHeapObject>(obj); |
| 1514 } | 1513 } |
| 1515 | 1514 |
| 1516 | 1515 void HGraphBuilder::FinishExitWithHardDeoptimization(DeoptimizeReason reason) { |
| 1517 void HGraphBuilder::FinishExitWithHardDeoptimization( | |
| 1518 Deoptimizer::DeoptReason reason) { | |
| 1519 Add<HDeoptimize>(reason, Deoptimizer::EAGER); | 1516 Add<HDeoptimize>(reason, Deoptimizer::EAGER); |
| 1520 FinishExitCurrentBlock(New<HAbnormalExit>()); | 1517 FinishExitCurrentBlock(New<HAbnormalExit>()); |
| 1521 } | 1518 } |
| 1522 | 1519 |
| 1523 | 1520 |
| 1524 HValue* HGraphBuilder::BuildCheckString(HValue* string) { | 1521 HValue* HGraphBuilder::BuildCheckString(HValue* string) { |
| 1525 if (!string->type().IsString()) { | 1522 if (!string->type().IsString()) { |
| 1526 DCHECK(!string->IsConstant() || | 1523 DCHECK(!string->IsConstant() || |
| 1527 !HConstant::cast(string)->HasStringValue()); | 1524 !HConstant::cast(string)->HasStringValue()); |
| 1528 BuildCheckHeapObject(string); | 1525 BuildCheckHeapObject(string); |
| (...skipping 297 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1826 // not one of the global object types. | 1823 // not one of the global object types. |
| 1827 HValue* map = | 1824 HValue* map = |
| 1828 Add<HLoadNamedField>(receiver, nullptr, HObjectAccess::ForMap()); | 1825 Add<HLoadNamedField>(receiver, nullptr, HObjectAccess::ForMap()); |
| 1829 HValue* instance_type = | 1826 HValue* instance_type = |
| 1830 Add<HLoadNamedField>(map, nullptr, HObjectAccess::ForMapInstanceType()); | 1827 Add<HLoadNamedField>(map, nullptr, HObjectAccess::ForMapInstanceType()); |
| 1831 HValue* global_type = Add<HConstant>(JS_GLOBAL_OBJECT_TYPE); | 1828 HValue* global_type = Add<HConstant>(JS_GLOBAL_OBJECT_TYPE); |
| 1832 | 1829 |
| 1833 IfBuilder if_global_object(this); | 1830 IfBuilder if_global_object(this); |
| 1834 if_global_object.If<HCompareNumericAndBranch>(instance_type, global_type, | 1831 if_global_object.If<HCompareNumericAndBranch>(instance_type, global_type, |
| 1835 Token::EQ); | 1832 Token::EQ); |
| 1836 if_global_object.ThenDeopt(Deoptimizer::kReceiverWasAGlobalObject); | 1833 if_global_object.ThenDeopt(DeoptimizeReason::kReceiverWasAGlobalObject); |
| 1837 if_global_object.End(); | 1834 if_global_object.End(); |
| 1838 } | 1835 } |
| 1839 | 1836 |
| 1840 | 1837 |
| 1841 void HGraphBuilder::BuildTestForDictionaryProperties( | 1838 void HGraphBuilder::BuildTestForDictionaryProperties( |
| 1842 HValue* object, | 1839 HValue* object, |
| 1843 HIfContinuation* continuation) { | 1840 HIfContinuation* continuation) { |
| 1844 HValue* properties = Add<HLoadNamedField>( | 1841 HValue* properties = Add<HLoadNamedField>( |
| 1845 object, nullptr, HObjectAccess::ForPropertiesPointer()); | 1842 object, nullptr, HObjectAccess::ForPropertiesPointer()); |
| 1846 HValue* properties_map = | 1843 HValue* properties_map = |
| (...skipping 329 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2176 if_objectiskey.Then(); | 2173 if_objectiskey.Then(); |
| 2177 { | 2174 { |
| 2178 // Make the key_index available. | 2175 // Make the key_index available. |
| 2179 Push(key_index); | 2176 Push(key_index); |
| 2180 } | 2177 } |
| 2181 if_objectiskey.JoinContinuation(&found); | 2178 if_objectiskey.JoinContinuation(&found); |
| 2182 } | 2179 } |
| 2183 if_objectissmi.Else(); | 2180 if_objectissmi.Else(); |
| 2184 { | 2181 { |
| 2185 if (type->Is(Type::SignedSmall())) { | 2182 if (type->Is(Type::SignedSmall())) { |
| 2186 if_objectissmi.Deopt(Deoptimizer::kExpectedSmi); | 2183 if_objectissmi.Deopt(DeoptimizeReason::kExpectedSmi); |
| 2187 } else { | 2184 } else { |
| 2188 // Check if the object is a heap number. | 2185 // Check if the object is a heap number. |
| 2189 IfBuilder if_objectisnumber(this); | 2186 IfBuilder if_objectisnumber(this); |
| 2190 HValue* objectisnumber = if_objectisnumber.If<HCompareMap>( | 2187 HValue* objectisnumber = if_objectisnumber.If<HCompareMap>( |
| 2191 object, isolate()->factory()->heap_number_map()); | 2188 object, isolate()->factory()->heap_number_map()); |
| 2192 if_objectisnumber.Then(); | 2189 if_objectisnumber.Then(); |
| 2193 { | 2190 { |
| 2194 // Compute hash for heap number similar to double_get_hash(). | 2191 // Compute hash for heap number similar to double_get_hash(). |
| 2195 HValue* low = Add<HLoadNamedField>( | 2192 HValue* low = Add<HLoadNamedField>( |
| 2196 object, objectisnumber, | 2193 object, objectisnumber, |
| (...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2232 } | 2229 } |
| 2233 if_keyeqobject.JoinContinuation(&found); | 2230 if_keyeqobject.JoinContinuation(&found); |
| 2234 } | 2231 } |
| 2235 if_keyisheapnumber.JoinContinuation(&found); | 2232 if_keyisheapnumber.JoinContinuation(&found); |
| 2236 } | 2233 } |
| 2237 if_keyisnotsmi.JoinContinuation(&found); | 2234 if_keyisnotsmi.JoinContinuation(&found); |
| 2238 } | 2235 } |
| 2239 if_objectisnumber.Else(); | 2236 if_objectisnumber.Else(); |
| 2240 { | 2237 { |
| 2241 if (type->Is(Type::Number())) { | 2238 if (type->Is(Type::Number())) { |
| 2242 if_objectisnumber.Deopt(Deoptimizer::kExpectedHeapNumber); | 2239 if_objectisnumber.Deopt(DeoptimizeReason::kExpectedHeapNumber); |
| 2243 } | 2240 } |
| 2244 } | 2241 } |
| 2245 if_objectisnumber.JoinContinuation(&found); | 2242 if_objectisnumber.JoinContinuation(&found); |
| 2246 } | 2243 } |
| 2247 } | 2244 } |
| 2248 if_objectissmi.JoinContinuation(&found); | 2245 if_objectissmi.JoinContinuation(&found); |
| 2249 | 2246 |
| 2250 // Check for cache hit. | 2247 // Check for cache hit. |
| 2251 IfBuilder if_found(this, &found); | 2248 IfBuilder if_found(this, &found); |
| 2252 if_found.Then(); | 2249 if_found.Then(); |
| (...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2325 receiver_map, nullptr, | 2322 receiver_map, nullptr, |
| 2326 HObjectAccess::ForMapInObjectPropertiesOrConstructorFunctionIndex()); | 2323 HObjectAccess::ForMapInObjectPropertiesOrConstructorFunctionIndex()); |
| 2327 | 2324 |
| 2328 // Check if {receiver} has a constructor (null and undefined have no | 2325 // Check if {receiver} has a constructor (null and undefined have no |
| 2329 // constructors, so we deoptimize to the runtime to throw an exception). | 2326 // constructors, so we deoptimize to the runtime to throw an exception). |
| 2330 IfBuilder constructor_function_index_is_invalid(this); | 2327 IfBuilder constructor_function_index_is_invalid(this); |
| 2331 constructor_function_index_is_invalid.If<HCompareNumericAndBranch>( | 2328 constructor_function_index_is_invalid.If<HCompareNumericAndBranch>( |
| 2332 constructor_function_index, | 2329 constructor_function_index, |
| 2333 Add<HConstant>(Map::kNoConstructorFunctionIndex), Token::EQ); | 2330 Add<HConstant>(Map::kNoConstructorFunctionIndex), Token::EQ); |
| 2334 constructor_function_index_is_invalid.ThenDeopt( | 2331 constructor_function_index_is_invalid.ThenDeopt( |
| 2335 Deoptimizer::kUndefinedOrNullInToObject); | 2332 DeoptimizeReason::kUndefinedOrNullInToObject); |
| 2336 constructor_function_index_is_invalid.End(); | 2333 constructor_function_index_is_invalid.End(); |
| 2337 | 2334 |
| 2338 // Use the global constructor function. | 2335 // Use the global constructor function. |
| 2339 Push(constructor_function_index); | 2336 Push(constructor_function_index); |
| 2340 } | 2337 } |
| 2341 receiver_is_not_spec_object.JoinContinuation(&wrap); | 2338 receiver_is_not_spec_object.JoinContinuation(&wrap); |
| 2342 } | 2339 } |
| 2343 receiver_is_smi.JoinContinuation(&wrap); | 2340 receiver_is_smi.JoinContinuation(&wrap); |
| 2344 | 2341 |
| 2345 // Wrap the receiver if necessary. | 2342 // Wrap the receiver if necessary. |
| (...skipping 487 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2833 IfBuilder length_checker(this); | 2830 IfBuilder length_checker(this); |
| 2834 length_checker.If<HCompareNumericAndBranch>(key, length, Token::LT); | 2831 length_checker.If<HCompareNumericAndBranch>(key, length, Token::LT); |
| 2835 length_checker.Then(); | 2832 length_checker.Then(); |
| 2836 IfBuilder negative_checker(this); | 2833 IfBuilder negative_checker(this); |
| 2837 HValue* bounds_check = negative_checker.If<HCompareNumericAndBranch>( | 2834 HValue* bounds_check = negative_checker.If<HCompareNumericAndBranch>( |
| 2838 key, graph()->GetConstant0(), Token::GTE); | 2835 key, graph()->GetConstant0(), Token::GTE); |
| 2839 negative_checker.Then(); | 2836 negative_checker.Then(); |
| 2840 HInstruction* result = AddElementAccess( | 2837 HInstruction* result = AddElementAccess( |
| 2841 backing_store, key, val, bounds_check, checked_object->ActualValue(), | 2838 backing_store, key, val, bounds_check, checked_object->ActualValue(), |
| 2842 elements_kind, access_type); | 2839 elements_kind, access_type); |
| 2843 negative_checker.ElseDeopt(Deoptimizer::kNegativeKeyEncountered); | 2840 negative_checker.ElseDeopt(DeoptimizeReason::kNegativeKeyEncountered); |
| 2844 negative_checker.End(); | 2841 negative_checker.End(); |
| 2845 length_checker.End(); | 2842 length_checker.End(); |
| 2846 return result; | 2843 return result; |
| 2847 } else { | 2844 } else { |
| 2848 DCHECK(store_mode == STANDARD_STORE); | 2845 DCHECK(store_mode == STANDARD_STORE); |
| 2849 checked_key = Add<HBoundsCheck>(key, length); | 2846 checked_key = Add<HBoundsCheck>(key, length); |
| 2850 return AddElementAccess(backing_store, checked_key, val, checked_object, | 2847 return AddElementAccess(backing_store, checked_key, val, checked_object, |
| 2851 checked_object->ActualValue(), elements_kind, | 2848 checked_object->ActualValue(), elements_kind, |
| 2852 access_type); | 2849 access_type); |
| 2853 } | 2850 } |
| (...skipping 2411 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5265 | 5262 |
| 5266 CHECK_ALIVE(VisitForValue(stmt->enumerable())); | 5263 CHECK_ALIVE(VisitForValue(stmt->enumerable())); |
| 5267 HValue* enumerable = Top(); // Leave enumerable at the top. | 5264 HValue* enumerable = Top(); // Leave enumerable at the top. |
| 5268 | 5265 |
| 5269 IfBuilder if_undefined_or_null(this); | 5266 IfBuilder if_undefined_or_null(this); |
| 5270 if_undefined_or_null.If<HCompareObjectEqAndBranch>( | 5267 if_undefined_or_null.If<HCompareObjectEqAndBranch>( |
| 5271 enumerable, graph()->GetConstantUndefined()); | 5268 enumerable, graph()->GetConstantUndefined()); |
| 5272 if_undefined_or_null.Or(); | 5269 if_undefined_or_null.Or(); |
| 5273 if_undefined_or_null.If<HCompareObjectEqAndBranch>( | 5270 if_undefined_or_null.If<HCompareObjectEqAndBranch>( |
| 5274 enumerable, graph()->GetConstantNull()); | 5271 enumerable, graph()->GetConstantNull()); |
| 5275 if_undefined_or_null.ThenDeopt(Deoptimizer::kUndefinedOrNullInForIn); | 5272 if_undefined_or_null.ThenDeopt(DeoptimizeReason::kUndefinedOrNullInForIn); |
| 5276 if_undefined_or_null.End(); | 5273 if_undefined_or_null.End(); |
| 5277 BuildForInBody(stmt, each_var, enumerable); | 5274 BuildForInBody(stmt, each_var, enumerable); |
| 5278 } | 5275 } |
| 5279 | 5276 |
| 5280 | 5277 |
| 5281 void HOptimizedGraphBuilder::BuildForInBody(ForInStatement* stmt, | 5278 void HOptimizedGraphBuilder::BuildForInBody(ForInStatement* stmt, |
| 5282 Variable* each_var, | 5279 Variable* each_var, |
| 5283 HValue* enumerable) { | 5280 HValue* enumerable) { |
| 5284 Handle<Map> meta_map = isolate()->factory()->meta_map(); | 5281 Handle<Map> meta_map = isolate()->factory()->meta_map(); |
| 5285 bool fast = stmt->for_in_type() == ForInStatement::FAST_FOR_IN; | 5282 bool fast = stmt->for_in_type() == ForInStatement::FAST_FOR_IN; |
| (...skipping 1391 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 6677 | 6674 |
| 6678 if (current_block() != NULL) Goto(join); | 6675 if (current_block() != NULL) Goto(join); |
| 6679 set_current_block(if_false); | 6676 set_current_block(if_false); |
| 6680 } | 6677 } |
| 6681 | 6678 |
| 6682 // Finish up. Unconditionally deoptimize if we've handled all the maps we | 6679 // Finish up. Unconditionally deoptimize if we've handled all the maps we |
| 6683 // know about and do not want to handle ones we've never seen. Otherwise | 6680 // know about and do not want to handle ones we've never seen. Otherwise |
| 6684 // use a generic IC. | 6681 // use a generic IC. |
| 6685 if (count == maps->length() && FLAG_deoptimize_uncommon_cases) { | 6682 if (count == maps->length() && FLAG_deoptimize_uncommon_cases) { |
| 6686 FinishExitWithHardDeoptimization( | 6683 FinishExitWithHardDeoptimization( |
| 6687 Deoptimizer::kUnknownMapInPolymorphicAccess); | 6684 DeoptimizeReason::kUnknownMapInPolymorphicAccess); |
| 6688 } else { | 6685 } else { |
| 6689 HInstruction* instr = | 6686 HInstruction* instr = |
| 6690 BuildNamedGeneric(access_type, expr, slot, object, name, value); | 6687 BuildNamedGeneric(access_type, expr, slot, object, name, value); |
| 6691 AddInstruction(instr); | 6688 AddInstruction(instr); |
| 6692 if (!ast_context()->IsEffect()) Push(access_type == LOAD ? instr : value); | 6689 if (!ast_context()->IsEffect()) Push(access_type == LOAD ? instr : value); |
| 6693 | 6690 |
| 6694 if (join != NULL) { | 6691 if (join != NULL) { |
| 6695 Goto(join); | 6692 Goto(join); |
| 6696 } else { | 6693 } else { |
| 6697 Add<HSimulate>(ast_id, REMOVABLE_SIMULATE); | 6694 Add<HSimulate>(ast_id, REMOVABLE_SIMULATE); |
| (...skipping 165 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 6863 if (type == kUseCell) { | 6860 if (type == kUseCell) { |
| 6864 Handle<PropertyCell> cell = it.GetPropertyCell(); | 6861 Handle<PropertyCell> cell = it.GetPropertyCell(); |
| 6865 top_info()->dependencies()->AssumePropertyCell(cell); | 6862 top_info()->dependencies()->AssumePropertyCell(cell); |
| 6866 auto cell_type = it.property_details().cell_type(); | 6863 auto cell_type = it.property_details().cell_type(); |
| 6867 if (cell_type == PropertyCellType::kConstant || | 6864 if (cell_type == PropertyCellType::kConstant || |
| 6868 cell_type == PropertyCellType::kUndefined) { | 6865 cell_type == PropertyCellType::kUndefined) { |
| 6869 Handle<Object> constant(cell->value(), isolate()); | 6866 Handle<Object> constant(cell->value(), isolate()); |
| 6870 if (value->IsConstant()) { | 6867 if (value->IsConstant()) { |
| 6871 HConstant* c_value = HConstant::cast(value); | 6868 HConstant* c_value = HConstant::cast(value); |
| 6872 if (!constant.is_identical_to(c_value->handle(isolate()))) { | 6869 if (!constant.is_identical_to(c_value->handle(isolate()))) { |
| 6873 Add<HDeoptimize>(Deoptimizer::kConstantGlobalVariableAssignment, | 6870 Add<HDeoptimize>(DeoptimizeReason::kConstantGlobalVariableAssignment, |
| 6874 Deoptimizer::EAGER); | 6871 Deoptimizer::EAGER); |
| 6875 } | 6872 } |
| 6876 } else { | 6873 } else { |
| 6877 HValue* c_constant = Add<HConstant>(constant); | 6874 HValue* c_constant = Add<HConstant>(constant); |
| 6878 IfBuilder builder(this); | 6875 IfBuilder builder(this); |
| 6879 if (constant->IsNumber()) { | 6876 if (constant->IsNumber()) { |
| 6880 builder.If<HCompareNumericAndBranch>(value, c_constant, Token::EQ); | 6877 builder.If<HCompareNumericAndBranch>(value, c_constant, Token::EQ); |
| 6881 } else { | 6878 } else { |
| 6882 builder.If<HCompareObjectEqAndBranch>(value, c_constant); | 6879 builder.If<HCompareObjectEqAndBranch>(value, c_constant); |
| 6883 } | 6880 } |
| 6884 builder.Then(); | 6881 builder.Then(); |
| 6885 builder.Else(); | 6882 builder.Else(); |
| 6886 Add<HDeoptimize>(Deoptimizer::kConstantGlobalVariableAssignment, | 6883 Add<HDeoptimize>(DeoptimizeReason::kConstantGlobalVariableAssignment, |
| 6887 Deoptimizer::EAGER); | 6884 Deoptimizer::EAGER); |
| 6888 builder.End(); | 6885 builder.End(); |
| 6889 } | 6886 } |
| 6890 } | 6887 } |
| 6891 HConstant* cell_constant = Add<HConstant>(cell); | 6888 HConstant* cell_constant = Add<HConstant>(cell); |
| 6892 auto access = HObjectAccess::ForPropertyCellValue(); | 6889 auto access = HObjectAccess::ForPropertyCellValue(); |
| 6893 if (cell_type == PropertyCellType::kConstantType) { | 6890 if (cell_type == PropertyCellType::kConstantType) { |
| 6894 switch (cell->GetConstantType()) { | 6891 switch (cell->GetConstantType()) { |
| 6895 case PropertyCellConstantType::kSmi: | 6892 case PropertyCellConstantType::kSmi: |
| 6896 access = access.WithRepresentation(Representation::Smi()); | 6893 access = access.WithRepresentation(Representation::Smi()); |
| (...skipping 328 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 7225 return New<HLoadNamedField>(string, nullptr, | 7222 return New<HLoadNamedField>(string, nullptr, |
| 7226 HObjectAccess::ForStringLength()); | 7223 HObjectAccess::ForStringLength()); |
| 7227 } | 7224 } |
| 7228 | 7225 |
| 7229 | 7226 |
| 7230 HInstruction* HOptimizedGraphBuilder::BuildNamedGeneric( | 7227 HInstruction* HOptimizedGraphBuilder::BuildNamedGeneric( |
| 7231 PropertyAccessType access_type, Expression* expr, FeedbackVectorSlot slot, | 7228 PropertyAccessType access_type, Expression* expr, FeedbackVectorSlot slot, |
| 7232 HValue* object, Handle<Name> name, HValue* value, bool is_uninitialized) { | 7229 HValue* object, Handle<Name> name, HValue* value, bool is_uninitialized) { |
| 7233 if (is_uninitialized) { | 7230 if (is_uninitialized) { |
| 7234 Add<HDeoptimize>( | 7231 Add<HDeoptimize>( |
| 7235 Deoptimizer::kInsufficientTypeFeedbackForGenericNamedAccess, | 7232 DeoptimizeReason::kInsufficientTypeFeedbackForGenericNamedAccess, |
| 7236 Deoptimizer::SOFT); | 7233 Deoptimizer::SOFT); |
| 7237 } | 7234 } |
| 7238 if (access_type == LOAD) { | 7235 if (access_type == LOAD) { |
| 7239 Handle<TypeFeedbackVector> vector = | 7236 Handle<TypeFeedbackVector> vector = |
| 7240 handle(current_feedback_vector(), isolate()); | 7237 handle(current_feedback_vector(), isolate()); |
| 7241 | 7238 |
| 7242 if (!expr->AsProperty()->key()->IsPropertyName()) { | 7239 if (!expr->AsProperty()->key()->IsPropertyName()) { |
| 7243 // It's possible that a keyed load of a constant string was converted | 7240 // It's possible that a keyed load of a constant string was converted |
| 7244 // to a named load. Here, at the last minute, we need to make sure to | 7241 // to a named load. Here, at the last minute, we need to make sure to |
| 7245 // use a generic Keyed Load if we are using the type vector, because | 7242 // use a generic Keyed Load if we are using the type vector, because |
| (...skipping 337 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 7583 } | 7580 } |
| 7584 | 7581 |
| 7585 // Ensure that we visited at least one map above that goes to join. This is | 7582 // Ensure that we visited at least one map above that goes to join. This is |
| 7586 // necessary because FinishExitWithHardDeoptimization does an AbnormalExit | 7583 // necessary because FinishExitWithHardDeoptimization does an AbnormalExit |
| 7587 // rather than joining the join block. If this becomes an issue, insert a | 7584 // rather than joining the join block. If this becomes an issue, insert a |
| 7588 // generic access in the case length() == 0. | 7585 // generic access in the case length() == 0. |
| 7589 DCHECK(join->predecessors()->length() > 0); | 7586 DCHECK(join->predecessors()->length() > 0); |
| 7590 // Deopt if none of the cases matched. | 7587 // Deopt if none of the cases matched. |
| 7591 NoObservableSideEffectsScope scope(this); | 7588 NoObservableSideEffectsScope scope(this); |
| 7592 FinishExitWithHardDeoptimization( | 7589 FinishExitWithHardDeoptimization( |
| 7593 Deoptimizer::kUnknownMapInPolymorphicElementAccess); | 7590 DeoptimizeReason::kUnknownMapInPolymorphicElementAccess); |
| 7594 set_current_block(join); | 7591 set_current_block(join); |
| 7595 return access_type == STORE ? val : Pop(); | 7592 return access_type == STORE ? val : Pop(); |
| 7596 } | 7593 } |
| 7597 | 7594 |
| 7598 HValue* HOptimizedGraphBuilder::HandleKeyedElementAccess( | 7595 HValue* HOptimizedGraphBuilder::HandleKeyedElementAccess( |
| 7599 HValue* obj, HValue* key, HValue* val, Expression* expr, | 7596 HValue* obj, HValue* key, HValue* val, Expression* expr, |
| 7600 FeedbackVectorSlot slot, BailoutId ast_id, BailoutId return_id, | 7597 FeedbackVectorSlot slot, BailoutId ast_id, BailoutId return_id, |
| 7601 PropertyAccessType access_type, bool* has_side_effects) { | 7598 PropertyAccessType access_type, bool* has_side_effects) { |
| 7602 // A keyed name access with type feedback may contain the name. | 7599 // A keyed name access with type feedback may contain the name. |
| 7603 Handle<TypeFeedbackVector> vector = | 7600 Handle<TypeFeedbackVector> vector = |
| (...skipping 96 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 7700 obj, key, val, NULL, map, access_type, expr->GetStoreMode()); | 7697 obj, key, val, NULL, map, access_type, expr->GetStoreMode()); |
| 7701 } | 7698 } |
| 7702 } else if (!force_generic && (maps != NULL && !maps->is_empty())) { | 7699 } else if (!force_generic && (maps != NULL && !maps->is_empty())) { |
| 7703 return HandlePolymorphicElementAccess(expr, slot, obj, key, val, maps, | 7700 return HandlePolymorphicElementAccess(expr, slot, obj, key, val, maps, |
| 7704 access_type, expr->GetStoreMode(), | 7701 access_type, expr->GetStoreMode(), |
| 7705 has_side_effects); | 7702 has_side_effects); |
| 7706 } else { | 7703 } else { |
| 7707 if (access_type == STORE) { | 7704 if (access_type == STORE) { |
| 7708 if (expr->IsAssignment() && | 7705 if (expr->IsAssignment() && |
| 7709 expr->AsAssignment()->HasNoTypeInformation()) { | 7706 expr->AsAssignment()->HasNoTypeInformation()) { |
| 7710 Add<HDeoptimize>(Deoptimizer::kInsufficientTypeFeedbackForKeyedStore, | 7707 Add<HDeoptimize>( |
| 7711 Deoptimizer::SOFT); | 7708 DeoptimizeReason::kInsufficientTypeFeedbackForGenericKeyedAccess, |
| 7709 Deoptimizer::SOFT); |
| 7712 } | 7710 } |
| 7713 } else { | 7711 } else { |
| 7714 if (expr->AsProperty()->HasNoTypeInformation()) { | 7712 if (expr->AsProperty()->HasNoTypeInformation()) { |
| 7715 Add<HDeoptimize>(Deoptimizer::kInsufficientTypeFeedbackForKeyedLoad, | 7713 Add<HDeoptimize>( |
| 7716 Deoptimizer::SOFT); | 7714 DeoptimizeReason::kInsufficientTypeFeedbackForGenericKeyedAccess, |
| 7715 Deoptimizer::SOFT); |
| 7717 } | 7716 } |
| 7718 } | 7717 } |
| 7719 instr = AddInstruction( | 7718 instr = AddInstruction( |
| 7720 BuildKeyedGeneric(access_type, expr, slot, obj, key, val)); | 7719 BuildKeyedGeneric(access_type, expr, slot, obj, key, val)); |
| 7721 } | 7720 } |
| 7722 *has_side_effects = instr->HasObservableSideEffects(); | 7721 *has_side_effects = instr->HasObservableSideEffects(); |
| 7723 return instr; | 7722 return instr; |
| 7724 } | 7723 } |
| 7725 | 7724 |
| 7726 | 7725 |
| (...skipping 456 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 8183 } | 8182 } |
| 8184 | 8183 |
| 8185 if (current_block() != NULL) Goto(join); | 8184 if (current_block() != NULL) Goto(join); |
| 8186 set_current_block(if_false); | 8185 set_current_block(if_false); |
| 8187 } | 8186 } |
| 8188 | 8187 |
| 8189 // Finish up. Unconditionally deoptimize if we've handled all the maps we | 8188 // Finish up. Unconditionally deoptimize if we've handled all the maps we |
| 8190 // know about and do not want to handle ones we've never seen. Otherwise | 8189 // know about and do not want to handle ones we've never seen. Otherwise |
| 8191 // use a generic IC. | 8190 // use a generic IC. |
| 8192 if (ordered_functions == maps->length() && FLAG_deoptimize_uncommon_cases) { | 8191 if (ordered_functions == maps->length() && FLAG_deoptimize_uncommon_cases) { |
| 8193 FinishExitWithHardDeoptimization(Deoptimizer::kUnknownMapInPolymorphicCall); | 8192 FinishExitWithHardDeoptimization( |
| 8193 DeoptimizeReason::kUnknownMapInPolymorphicCall); |
| 8194 } else { | 8194 } else { |
| 8195 Property* prop = expr->expression()->AsProperty(); | 8195 Property* prop = expr->expression()->AsProperty(); |
| 8196 HInstruction* function = | 8196 HInstruction* function = |
| 8197 BuildNamedGeneric(LOAD, prop, prop->PropertyFeedbackSlot(), receiver, | 8197 BuildNamedGeneric(LOAD, prop, prop->PropertyFeedbackSlot(), receiver, |
| 8198 name, NULL, prop->IsUninitialized()); | 8198 name, NULL, prop->IsUninitialized()); |
| 8199 AddInstruction(function); | 8199 AddInstruction(function); |
| 8200 Push(function); | 8200 Push(function); |
| 8201 AddSimulate(prop->LoadId(), REMOVABLE_SIMULATE); | 8201 AddSimulate(prop->LoadId(), REMOVABLE_SIMULATE); |
| 8202 | 8202 |
| 8203 environment()->SetExpressionStackAt(1, function); | 8203 environment()->SetExpressionStackAt(1, function); |
| (...skipping 1589 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 9793 NewCallConstantFunction(known_function, argument_count, | 9793 NewCallConstantFunction(known_function, argument_count, |
| 9794 syntactic_tail_call_mode, tail_call_mode); | 9794 syntactic_tail_call_mode, tail_call_mode); |
| 9795 } | 9795 } |
| 9796 | 9796 |
| 9797 } else { | 9797 } else { |
| 9798 ArgumentsAllowedFlag arguments_flag = ARGUMENTS_NOT_ALLOWED; | 9798 ArgumentsAllowedFlag arguments_flag = ARGUMENTS_NOT_ALLOWED; |
| 9799 if (CanBeFunctionApplyArguments(expr) && expr->is_uninitialized()) { | 9799 if (CanBeFunctionApplyArguments(expr) && expr->is_uninitialized()) { |
| 9800 // We have to use EAGER deoptimization here because Deoptimizer::SOFT | 9800 // We have to use EAGER deoptimization here because Deoptimizer::SOFT |
| 9801 // gets ignored by the always-opt flag, which leads to incorrect code. | 9801 // gets ignored by the always-opt flag, which leads to incorrect code. |
| 9802 Add<HDeoptimize>( | 9802 Add<HDeoptimize>( |
| 9803 Deoptimizer::kInsufficientTypeFeedbackForCallWithArguments, | 9803 DeoptimizeReason::kInsufficientTypeFeedbackForCallWithArguments, |
| 9804 Deoptimizer::EAGER); | 9804 Deoptimizer::EAGER); |
| 9805 arguments_flag = ARGUMENTS_FAKED; | 9805 arguments_flag = ARGUMENTS_FAKED; |
| 9806 } | 9806 } |
| 9807 | 9807 |
| 9808 // Push the function under the receiver. | 9808 // Push the function under the receiver. |
| 9809 environment()->SetExpressionStackAt(0, function); | 9809 environment()->SetExpressionStackAt(0, function); |
| 9810 Push(receiver); | 9810 Push(receiver); |
| 9811 | 9811 |
| 9812 CHECK_ALIVE(VisitExpressions(expr->arguments(), arguments_flag)); | 9812 CHECK_ALIVE(VisitExpressions(expr->arguments(), arguments_flag)); |
| 9813 call = NewCallFunction(function, argument_count, syntactic_tail_call_mode, | 9813 call = NewCallFunction(function, argument_count, syntactic_tail_call_mode, |
| (...skipping 1217 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 11031 left_type->Maybe(Type::Receiver()) || | 11031 left_type->Maybe(Type::Receiver()) || |
| 11032 right_type->Maybe(Type::String()) || | 11032 right_type->Maybe(Type::String()) || |
| 11033 right_type->Maybe(Type::Receiver())); | 11033 right_type->Maybe(Type::Receiver())); |
| 11034 } | 11034 } |
| 11035 | 11035 |
| 11036 Representation left_rep = RepresentationFor(left_type); | 11036 Representation left_rep = RepresentationFor(left_type); |
| 11037 Representation right_rep = RepresentationFor(right_type); | 11037 Representation right_rep = RepresentationFor(right_type); |
| 11038 | 11038 |
| 11039 if (!left_type->IsInhabited()) { | 11039 if (!left_type->IsInhabited()) { |
| 11040 Add<HDeoptimize>( | 11040 Add<HDeoptimize>( |
| 11041 Deoptimizer::kInsufficientTypeFeedbackForLHSOfBinaryOperation, | 11041 DeoptimizeReason::kInsufficientTypeFeedbackForLHSOfBinaryOperation, |
| 11042 Deoptimizer::SOFT); | 11042 Deoptimizer::SOFT); |
| 11043 left_type = Type::Any(); | 11043 left_type = Type::Any(); |
| 11044 left_rep = RepresentationFor(left_type); | 11044 left_rep = RepresentationFor(left_type); |
| 11045 maybe_string_add = op == Token::ADD; | 11045 maybe_string_add = op == Token::ADD; |
| 11046 } | 11046 } |
| 11047 | 11047 |
| 11048 if (!right_type->IsInhabited()) { | 11048 if (!right_type->IsInhabited()) { |
| 11049 Add<HDeoptimize>( | 11049 Add<HDeoptimize>( |
| 11050 Deoptimizer::kInsufficientTypeFeedbackForRHSOfBinaryOperation, | 11050 DeoptimizeReason::kInsufficientTypeFeedbackForRHSOfBinaryOperation, |
| 11051 Deoptimizer::SOFT); | 11051 Deoptimizer::SOFT); |
| 11052 right_type = Type::Any(); | 11052 right_type = Type::Any(); |
| 11053 right_rep = RepresentationFor(right_type); | 11053 right_rep = RepresentationFor(right_type); |
| 11054 maybe_string_add = op == Token::ADD; | 11054 maybe_string_add = op == Token::ADD; |
| 11055 } | 11055 } |
| 11056 | 11056 |
| 11057 if (!maybe_string_add) { | 11057 if (!maybe_string_add) { |
| 11058 left = TruncateToNumber(left, &left_type); | 11058 left = TruncateToNumber(left, &left_type); |
| 11059 right = TruncateToNumber(right, &right_type); | 11059 right = TruncateToNumber(right, &right_type); |
| 11060 } | 11060 } |
| (...skipping 163 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 11224 instr = AddUncasted<HMul>(left, right); | 11224 instr = AddUncasted<HMul>(left, right); |
| 11225 break; | 11225 break; |
| 11226 case Token::MOD: { | 11226 case Token::MOD: { |
| 11227 if (fixed_right_arg.IsJust() && | 11227 if (fixed_right_arg.IsJust() && |
| 11228 !right->EqualsInteger32Constant(fixed_right_arg.FromJust())) { | 11228 !right->EqualsInteger32Constant(fixed_right_arg.FromJust())) { |
| 11229 HConstant* fixed_right = | 11229 HConstant* fixed_right = |
| 11230 Add<HConstant>(static_cast<int>(fixed_right_arg.FromJust())); | 11230 Add<HConstant>(static_cast<int>(fixed_right_arg.FromJust())); |
| 11231 IfBuilder if_same(this); | 11231 IfBuilder if_same(this); |
| 11232 if_same.If<HCompareNumericAndBranch>(right, fixed_right, Token::EQ); | 11232 if_same.If<HCompareNumericAndBranch>(right, fixed_right, Token::EQ); |
| 11233 if_same.Then(); | 11233 if_same.Then(); |
| 11234 if_same.ElseDeopt(Deoptimizer::kUnexpectedRHSOfBinaryOperation); | 11234 if_same.ElseDeopt(DeoptimizeReason::kUnexpectedRHSOfBinaryOperation); |
| 11235 right = fixed_right; | 11235 right = fixed_right; |
| 11236 } | 11236 } |
| 11237 instr = AddUncasted<HMod>(left, right); | 11237 instr = AddUncasted<HMod>(left, right); |
| 11238 break; | 11238 break; |
| 11239 } | 11239 } |
| 11240 case Token::DIV: | 11240 case Token::DIV: |
| 11241 instr = AddUncasted<HDiv>(left, right); | 11241 instr = AddUncasted<HDiv>(left, right); |
| 11242 break; | 11242 break; |
| 11243 case Token::BIT_XOR: | 11243 case Token::BIT_XOR: |
| 11244 case Token::BIT_AND: | 11244 case Token::BIT_AND: |
| (...skipping 351 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 11596 | 11596 |
| 11597 HControlInstruction* HOptimizedGraphBuilder::BuildCompareInstruction( | 11597 HControlInstruction* HOptimizedGraphBuilder::BuildCompareInstruction( |
| 11598 Token::Value op, HValue* left, HValue* right, Type* left_type, | 11598 Token::Value op, HValue* left, HValue* right, Type* left_type, |
| 11599 Type* right_type, Type* combined_type, SourcePosition left_position, | 11599 Type* right_type, Type* combined_type, SourcePosition left_position, |
| 11600 SourcePosition right_position, PushBeforeSimulateBehavior push_sim_result, | 11600 SourcePosition right_position, PushBeforeSimulateBehavior push_sim_result, |
| 11601 BailoutId bailout_id) { | 11601 BailoutId bailout_id) { |
| 11602 // Cases handled below depend on collected type feedback. They should | 11602 // Cases handled below depend on collected type feedback. They should |
| 11603 // soft deoptimize when there is no type feedback. | 11603 // soft deoptimize when there is no type feedback. |
| 11604 if (!combined_type->IsInhabited()) { | 11604 if (!combined_type->IsInhabited()) { |
| 11605 Add<HDeoptimize>( | 11605 Add<HDeoptimize>( |
| 11606 Deoptimizer::kInsufficientTypeFeedbackForCombinedTypeOfBinaryOperation, | 11606 DeoptimizeReason:: |
| 11607 kInsufficientTypeFeedbackForCombinedTypeOfBinaryOperation, |
| 11607 Deoptimizer::SOFT); | 11608 Deoptimizer::SOFT); |
| 11608 combined_type = left_type = right_type = Type::Any(); | 11609 combined_type = left_type = right_type = Type::Any(); |
| 11609 } | 11610 } |
| 11610 | 11611 |
| 11611 Representation left_rep = RepresentationFor(left_type); | 11612 Representation left_rep = RepresentationFor(left_type); |
| 11612 Representation right_rep = RepresentationFor(right_type); | 11613 Representation right_rep = RepresentationFor(right_type); |
| 11613 Representation combined_rep = RepresentationFor(combined_type); | 11614 Representation combined_rep = RepresentationFor(combined_type); |
| 11614 | 11615 |
| 11615 if (combined_type->Is(Type::Receiver())) { | 11616 if (combined_type->Is(Type::Receiver())) { |
| 11616 if (Token::IsEqualityOp(op)) { | 11617 if (Token::IsEqualityOp(op)) { |
| 11617 // HCompareObjectEqAndBranch can only deal with object, so | 11618 // HCompareObjectEqAndBranch can only deal with object, so |
| 11618 // exclude numbers. | 11619 // exclude numbers. |
| 11619 if ((left->IsConstant() && | 11620 if ((left->IsConstant() && |
| 11620 HConstant::cast(left)->HasNumberValue()) || | 11621 HConstant::cast(left)->HasNumberValue()) || |
| 11621 (right->IsConstant() && | 11622 (right->IsConstant() && |
| 11622 HConstant::cast(right)->HasNumberValue())) { | 11623 HConstant::cast(right)->HasNumberValue())) { |
| 11623 Add<HDeoptimize>(Deoptimizer::kTypeMismatchBetweenFeedbackAndConstant, | 11624 Add<HDeoptimize>( |
| 11624 Deoptimizer::SOFT); | 11625 DeoptimizeReason::kTypeMismatchBetweenFeedbackAndConstant, |
| 11626 Deoptimizer::SOFT); |
| 11625 // The caller expects a branch instruction, so make it happy. | 11627 // The caller expects a branch instruction, so make it happy. |
| 11626 return New<HBranch>(graph()->GetConstantTrue()); | 11628 return New<HBranch>(graph()->GetConstantTrue()); |
| 11627 } | 11629 } |
| 11628 // Can we get away with map check and not instance type check? | 11630 // Can we get away with map check and not instance type check? |
| 11629 HValue* operand_to_check = | 11631 HValue* operand_to_check = |
| 11630 left->block()->block_id() < right->block()->block_id() ? left : right; | 11632 left->block()->block_id() < right->block()->block_id() ? left : right; |
| 11631 if (combined_type->IsClass()) { | 11633 if (combined_type->IsClass()) { |
| 11632 Handle<Map> map = combined_type->AsClass()->Map(); | 11634 Handle<Map> map = combined_type->AsClass()->Map(); |
| 11633 AddCheckMap(operand_to_check, map); | 11635 AddCheckMap(operand_to_check, map); |
| 11634 HCompareObjectEqAndBranch* result = | 11636 HCompareObjectEqAndBranch* result = |
| (...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 11696 return NULL; | 11698 return NULL; |
| 11697 } | 11699 } |
| 11698 } else if (combined_type->Is(Type::InternalizedString()) && | 11700 } else if (combined_type->Is(Type::InternalizedString()) && |
| 11699 Token::IsEqualityOp(op)) { | 11701 Token::IsEqualityOp(op)) { |
| 11700 // If we have a constant argument, it should be consistent with the type | 11702 // If we have a constant argument, it should be consistent with the type |
| 11701 // feedback (otherwise we fail assertions in HCompareObjectEqAndBranch). | 11703 // feedback (otherwise we fail assertions in HCompareObjectEqAndBranch). |
| 11702 if ((left->IsConstant() && | 11704 if ((left->IsConstant() && |
| 11703 !HConstant::cast(left)->HasInternalizedStringValue()) || | 11705 !HConstant::cast(left)->HasInternalizedStringValue()) || |
| 11704 (right->IsConstant() && | 11706 (right->IsConstant() && |
| 11705 !HConstant::cast(right)->HasInternalizedStringValue())) { | 11707 !HConstant::cast(right)->HasInternalizedStringValue())) { |
| 11706 Add<HDeoptimize>(Deoptimizer::kTypeMismatchBetweenFeedbackAndConstant, | 11708 Add<HDeoptimize>( |
| 11707 Deoptimizer::SOFT); | 11709 DeoptimizeReason::kTypeMismatchBetweenFeedbackAndConstant, |
| 11710 Deoptimizer::SOFT); |
| 11708 // The caller expects a branch instruction, so make it happy. | 11711 // The caller expects a branch instruction, so make it happy. |
| 11709 return New<HBranch>(graph()->GetConstantTrue()); | 11712 return New<HBranch>(graph()->GetConstantTrue()); |
| 11710 } | 11713 } |
| 11711 BuildCheckHeapObject(left); | 11714 BuildCheckHeapObject(left); |
| 11712 Add<HCheckInstanceType>(left, HCheckInstanceType::IS_INTERNALIZED_STRING); | 11715 Add<HCheckInstanceType>(left, HCheckInstanceType::IS_INTERNALIZED_STRING); |
| 11713 BuildCheckHeapObject(right); | 11716 BuildCheckHeapObject(right); |
| 11714 Add<HCheckInstanceType>(right, HCheckInstanceType::IS_INTERNALIZED_STRING); | 11717 Add<HCheckInstanceType>(right, HCheckInstanceType::IS_INTERNALIZED_STRING); |
| 11715 HCompareObjectEqAndBranch* result = | 11718 HCompareObjectEqAndBranch* result = |
| 11716 New<HCompareObjectEqAndBranch>(left, right); | 11719 New<HCompareObjectEqAndBranch>(left, right); |
| 11717 return result; | 11720 return result; |
| (...skipping 1697 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 13415 isolate()->GetHTracer()->TraceHydrogen(name(), graph_); | 13418 isolate()->GetHTracer()->TraceHydrogen(name(), graph_); |
| 13416 } | 13419 } |
| 13417 | 13420 |
| 13418 #ifdef DEBUG | 13421 #ifdef DEBUG |
| 13419 graph_->Verify(false); // No full verify. | 13422 graph_->Verify(false); // No full verify. |
| 13420 #endif | 13423 #endif |
| 13421 } | 13424 } |
| 13422 | 13425 |
| 13423 } // namespace internal | 13426 } // namespace internal |
| 13424 } // namespace v8 | 13427 } // namespace v8 |
| OLD | NEW |