| 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/hydrogen.h" | 5 #include "src/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-numbering.h" | 10 #include "src/ast-numbering.h" |
| (...skipping 1547 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1558 IfBuilder internalized(this); | 1558 IfBuilder internalized(this); |
| 1559 internalized.If<HCompareNumericAndBranch>(not_internalized_bit, | 1559 internalized.If<HCompareNumericAndBranch>(not_internalized_bit, |
| 1560 graph()->GetConstant0(), | 1560 graph()->GetConstant0(), |
| 1561 Token::EQ); | 1561 Token::EQ); |
| 1562 internalized.Then(); | 1562 internalized.Then(); |
| 1563 Push(key); | 1563 Push(key); |
| 1564 | 1564 |
| 1565 internalized.Else(); | 1565 internalized.Else(); |
| 1566 Add<HPushArguments>(key); | 1566 Add<HPushArguments>(key); |
| 1567 HValue* intern_key = Add<HCallRuntime>( | 1567 HValue* intern_key = Add<HCallRuntime>( |
| 1568 isolate()->factory()->empty_string(), | |
| 1569 Runtime::FunctionForId(Runtime::kInternalizeString), 1); | 1568 Runtime::FunctionForId(Runtime::kInternalizeString), 1); |
| 1570 Push(intern_key); | 1569 Push(intern_key); |
| 1571 | 1570 |
| 1572 internalized.End(); | 1571 internalized.End(); |
| 1573 // Key guaranteed to be a unique string | 1572 // Key guaranteed to be a unique string |
| 1574 } | 1573 } |
| 1575 string_index_if.JoinContinuation(join_continuation); | 1574 string_index_if.JoinContinuation(join_continuation); |
| 1576 } | 1575 } |
| 1577 not_symbol_if.Else(); | 1576 not_symbol_if.Else(); |
| 1578 { | 1577 { |
| (...skipping 137 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1716 Add<HLoadKeyed>(elements, key_index, nullptr, FAST_ELEMENTS); | 1715 Add<HLoadKeyed>(elements, key_index, nullptr, FAST_ELEMENTS); |
| 1717 IfBuilder if_undefined(this); | 1716 IfBuilder if_undefined(this); |
| 1718 if_undefined.If<HCompareObjectEqAndBranch>(candidate_key, | 1717 if_undefined.If<HCompareObjectEqAndBranch>(candidate_key, |
| 1719 graph()->GetConstantUndefined()); | 1718 graph()->GetConstantUndefined()); |
| 1720 if_undefined.Then(); | 1719 if_undefined.Then(); |
| 1721 { | 1720 { |
| 1722 // element == undefined means "not found". Call the runtime. | 1721 // element == undefined means "not found". Call the runtime. |
| 1723 // TODO(jkummerow): walk the prototype chain instead. | 1722 // TODO(jkummerow): walk the prototype chain instead. |
| 1724 Add<HPushArguments>(receiver, key); | 1723 Add<HPushArguments>(receiver, key); |
| 1725 Push(Add<HCallRuntime>( | 1724 Push(Add<HCallRuntime>( |
| 1726 isolate()->factory()->empty_string(), | |
| 1727 Runtime::FunctionForId(is_strong(language_mode) | 1725 Runtime::FunctionForId(is_strong(language_mode) |
| 1728 ? Runtime::kKeyedGetPropertyStrong | 1726 ? Runtime::kKeyedGetPropertyStrong |
| 1729 : Runtime::kKeyedGetProperty), | 1727 : Runtime::kKeyedGetProperty), |
| 1730 2)); | 1728 2)); |
| 1731 } | 1729 } |
| 1732 if_undefined.Else(); | 1730 if_undefined.Else(); |
| 1733 { | 1731 { |
| 1734 IfBuilder if_match(this); | 1732 IfBuilder if_match(this); |
| 1735 if_match.If<HCompareObjectEqAndBranch>(candidate_key, key); | 1733 if_match.If<HCompareObjectEqAndBranch>(candidate_key, key); |
| 1736 if_match.Then(); | 1734 if_match.Then(); |
| (...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1779 details_compare.If<HCompareNumericAndBranch>( | 1777 details_compare.If<HCompareNumericAndBranch>( |
| 1780 details, graph()->GetConstant0(), Token::EQ); | 1778 details, graph()->GetConstant0(), Token::EQ); |
| 1781 details_compare.Then(); | 1779 details_compare.Then(); |
| 1782 HValue* result_index = | 1780 HValue* result_index = |
| 1783 AddUncasted<HAdd>(base_index, Add<HConstant>(start_offset + 1)); | 1781 AddUncasted<HAdd>(base_index, Add<HConstant>(start_offset + 1)); |
| 1784 result_index->ClearFlag(HValue::kCanOverflow); | 1782 result_index->ClearFlag(HValue::kCanOverflow); |
| 1785 Push(Add<HLoadKeyed>(elements, result_index, nullptr, FAST_ELEMENTS)); | 1783 Push(Add<HLoadKeyed>(elements, result_index, nullptr, FAST_ELEMENTS)); |
| 1786 details_compare.Else(); | 1784 details_compare.Else(); |
| 1787 Add<HPushArguments>(receiver, key); | 1785 Add<HPushArguments>(receiver, key); |
| 1788 Push(Add<HCallRuntime>( | 1786 Push(Add<HCallRuntime>( |
| 1789 isolate()->factory()->empty_string(), | |
| 1790 Runtime::FunctionForId(is_strong(language_mode) | 1787 Runtime::FunctionForId(is_strong(language_mode) |
| 1791 ? Runtime::kKeyedGetPropertyStrong | 1788 ? Runtime::kKeyedGetPropertyStrong |
| 1792 : Runtime::kKeyedGetProperty), | 1789 : Runtime::kKeyedGetProperty), |
| 1793 2)); | 1790 2)); |
| 1794 details_compare.End(); | 1791 details_compare.End(); |
| 1795 | 1792 |
| 1796 found_key_match.Else(); | 1793 found_key_match.Else(); |
| 1797 found_key_match.JoinContinuation(&return_or_loop_continuation); | 1794 found_key_match.JoinContinuation(&return_or_loop_continuation); |
| 1798 } | 1795 } |
| 1799 if_undefined.JoinContinuation(&return_or_loop_continuation); | 1796 if_undefined.JoinContinuation(&return_or_loop_continuation); |
| (...skipping 213 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2013 HValue* key_index = Pop(); | 2010 HValue* key_index = Pop(); |
| 2014 HValue* value_index = AddUncasted<HAdd>(key_index, graph()->GetConstant1()); | 2011 HValue* value_index = AddUncasted<HAdd>(key_index, graph()->GetConstant1()); |
| 2015 Push(Add<HLoadKeyed>(number_string_cache, value_index, nullptr, | 2012 Push(Add<HLoadKeyed>(number_string_cache, value_index, nullptr, |
| 2016 FAST_ELEMENTS, ALLOW_RETURN_HOLE)); | 2013 FAST_ELEMENTS, ALLOW_RETURN_HOLE)); |
| 2017 } | 2014 } |
| 2018 if_found.Else(); | 2015 if_found.Else(); |
| 2019 { | 2016 { |
| 2020 // Cache miss, fallback to runtime. | 2017 // Cache miss, fallback to runtime. |
| 2021 Add<HPushArguments>(object); | 2018 Add<HPushArguments>(object); |
| 2022 Push(Add<HCallRuntime>( | 2019 Push(Add<HCallRuntime>( |
| 2023 isolate()->factory()->empty_string(), | |
| 2024 Runtime::FunctionForId(Runtime::kNumberToStringSkipCache), | 2020 Runtime::FunctionForId(Runtime::kNumberToStringSkipCache), |
| 2025 1)); | 2021 1)); |
| 2026 } | 2022 } |
| 2027 if_found.End(); | 2023 if_found.End(); |
| 2028 | 2024 |
| 2029 return Pop(); | 2025 return Pop(); |
| 2030 } | 2026 } |
| 2031 | 2027 |
| 2032 | 2028 |
| 2033 HValue* HGraphBuilder::BuildToObject(HValue* receiver) { | 2029 HValue* HGraphBuilder::BuildToObject(HValue* receiver) { |
| (...skipping 395 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2429 // Count the native string addition. | 2425 // Count the native string addition. |
| 2430 AddIncrementCounter(isolate()->counters()->string_add_native()); | 2426 AddIncrementCounter(isolate()->counters()->string_add_native()); |
| 2431 | 2427 |
| 2432 // Return the sequential string. | 2428 // Return the sequential string. |
| 2433 Push(result); | 2429 Push(result); |
| 2434 } | 2430 } |
| 2435 if_sameencodingandsequential.Else(); | 2431 if_sameencodingandsequential.Else(); |
| 2436 { | 2432 { |
| 2437 // Fallback to the runtime to add the two strings. | 2433 // Fallback to the runtime to add the two strings. |
| 2438 Add<HPushArguments>(left, right); | 2434 Add<HPushArguments>(left, right); |
| 2439 Push(Add<HCallRuntime>(isolate()->factory()->empty_string(), | 2435 Push(Add<HCallRuntime>(Runtime::FunctionForId(Runtime::kStringAdd), 2)); |
| 2440 Runtime::FunctionForId(Runtime::kStringAdd), 2)); | |
| 2441 } | 2436 } |
| 2442 if_sameencodingandsequential.End(); | 2437 if_sameencodingandsequential.End(); |
| 2443 } | 2438 } |
| 2444 if_createcons.End(); | 2439 if_createcons.End(); |
| 2445 | 2440 |
| 2446 return Pop(); | 2441 return Pop(); |
| 2447 } | 2442 } |
| 2448 | 2443 |
| 2449 | 2444 |
| 2450 HValue* HGraphBuilder::BuildStringAdd( | 2445 HValue* HGraphBuilder::BuildStringAdd( |
| (...skipping 2841 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5292 Add<HSimulate>(stmt->PrepareId()); | 5287 Add<HSimulate>(stmt->PrepareId()); |
| 5293 { | 5288 { |
| 5294 NoObservableSideEffectsScope no_effects(this); | 5289 NoObservableSideEffectsScope no_effects(this); |
| 5295 BuildJSObjectCheck(enumerable, 0); | 5290 BuildJSObjectCheck(enumerable, 0); |
| 5296 } | 5291 } |
| 5297 Add<HSimulate>(stmt->ToObjectId()); | 5292 Add<HSimulate>(stmt->ToObjectId()); |
| 5298 | 5293 |
| 5299 map = graph()->GetConstant1(); | 5294 map = graph()->GetConstant1(); |
| 5300 Runtime::FunctionId function_id = Runtime::kGetPropertyNamesFast; | 5295 Runtime::FunctionId function_id = Runtime::kGetPropertyNamesFast; |
| 5301 Add<HPushArguments>(enumerable); | 5296 Add<HPushArguments>(enumerable); |
| 5302 array = Add<HCallRuntime>(isolate()->factory()->empty_string(), | 5297 array = Add<HCallRuntime>(Runtime::FunctionForId(function_id), 1); |
| 5303 Runtime::FunctionForId(function_id), 1); | |
| 5304 Push(array); | 5298 Push(array); |
| 5305 Add<HSimulate>(stmt->EnumId()); | 5299 Add<HSimulate>(stmt->EnumId()); |
| 5306 Drop(1); | 5300 Drop(1); |
| 5307 Handle<Map> array_map = isolate()->factory()->fixed_array_map(); | 5301 Handle<Map> array_map = isolate()->factory()->fixed_array_map(); |
| 5308 HValue* check = Add<HCheckMaps>(array, array_map); | 5302 HValue* check = Add<HCheckMaps>(array, array_map); |
| 5309 enum_length = AddLoadFixedArrayLength(array, check); | 5303 enum_length = AddLoadFixedArrayLength(array, check); |
| 5310 } | 5304 } |
| 5311 | 5305 |
| 5312 HInstruction* start_index = Add<HConstant>(0); | 5306 HInstruction* start_index = Add<HConstant>(0); |
| 5313 | 5307 |
| (...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5348 index, index, FAST_ELEMENTS); | 5342 index, index, FAST_ELEMENTS); |
| 5349 | 5343 |
| 5350 if (fast) { | 5344 if (fast) { |
| 5351 // Check if the expected map still matches that of the enumerable. | 5345 // Check if the expected map still matches that of the enumerable. |
| 5352 // If not just deoptimize. | 5346 // If not just deoptimize. |
| 5353 Add<HCheckMapValue>(enumerable, environment()->ExpressionStackAt(3)); | 5347 Add<HCheckMapValue>(enumerable, environment()->ExpressionStackAt(3)); |
| 5354 Bind(each_var, key); | 5348 Bind(each_var, key); |
| 5355 } else { | 5349 } else { |
| 5356 Add<HPushArguments>(enumerable, key); | 5350 Add<HPushArguments>(enumerable, key); |
| 5357 Runtime::FunctionId function_id = Runtime::kForInFilter; | 5351 Runtime::FunctionId function_id = Runtime::kForInFilter; |
| 5358 key = Add<HCallRuntime>(isolate()->factory()->empty_string(), | 5352 key = Add<HCallRuntime>(Runtime::FunctionForId(function_id), 2); |
| 5359 Runtime::FunctionForId(function_id), 2); | |
| 5360 Push(key); | 5353 Push(key); |
| 5361 Add<HSimulate>(stmt->FilterId()); | 5354 Add<HSimulate>(stmt->FilterId()); |
| 5362 key = Pop(); | 5355 key = Pop(); |
| 5363 Bind(each_var, key); | 5356 Bind(each_var, key); |
| 5364 IfBuilder if_undefined(this); | 5357 IfBuilder if_undefined(this); |
| 5365 if_undefined.If<HCompareObjectEqAndBranch>(key, | 5358 if_undefined.If<HCompareObjectEqAndBranch>(key, |
| 5366 graph()->GetConstantUndefined()); | 5359 graph()->GetConstantUndefined()); |
| 5367 if_undefined.ThenDeopt(Deoptimizer::kUndefined); | 5360 if_undefined.ThenDeopt(Deoptimizer::kUndefined); |
| 5368 if_undefined.End(); | 5361 if_undefined.End(); |
| 5369 Add<HSimulate>(stmt->AssignmentId()); | 5362 Add<HSimulate>(stmt->AssignmentId()); |
| (...skipping 463 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5833 Handle<FixedArray> constant_properties = expr->constant_properties(); | 5826 Handle<FixedArray> constant_properties = expr->constant_properties(); |
| 5834 int literal_index = expr->literal_index(); | 5827 int literal_index = expr->literal_index(); |
| 5835 int flags = expr->ComputeFlags(true); | 5828 int flags = expr->ComputeFlags(true); |
| 5836 | 5829 |
| 5837 Add<HPushArguments>(Add<HConstant>(closure_literals), | 5830 Add<HPushArguments>(Add<HConstant>(closure_literals), |
| 5838 Add<HConstant>(literal_index), | 5831 Add<HConstant>(literal_index), |
| 5839 Add<HConstant>(constant_properties), | 5832 Add<HConstant>(constant_properties), |
| 5840 Add<HConstant>(flags)); | 5833 Add<HConstant>(flags)); |
| 5841 | 5834 |
| 5842 Runtime::FunctionId function_id = Runtime::kCreateObjectLiteral; | 5835 Runtime::FunctionId function_id = Runtime::kCreateObjectLiteral; |
| 5843 literal = Add<HCallRuntime>(isolate()->factory()->empty_string(), | 5836 literal = Add<HCallRuntime>(Runtime::FunctionForId(function_id), 4); |
| 5844 Runtime::FunctionForId(function_id), | |
| 5845 4); | |
| 5846 } | 5837 } |
| 5847 | 5838 |
| 5848 // The object is expected in the bailout environment during computation | 5839 // The object is expected in the bailout environment during computation |
| 5849 // of the property values and is the value of the entire expression. | 5840 // of the property values and is the value of the entire expression. |
| 5850 Push(literal); | 5841 Push(literal); |
| 5851 int store_slot_index = 0; | 5842 int store_slot_index = 0; |
| 5852 for (int i = 0; i < expr->properties()->length(); i++) { | 5843 for (int i = 0; i < expr->properties()->length(); i++) { |
| 5853 ObjectLiteral::Property* property = expr->properties()->at(i); | 5844 ObjectLiteral::Property* property = expr->properties()->at(i); |
| 5854 if (property->is_computed_name()) return Bailout(kComputedPropertyName); | 5845 if (property->is_computed_name()) return Bailout(kComputedPropertyName); |
| 5855 if (property->IsCompileTimeValue()) continue; | 5846 if (property->IsCompileTimeValue()) continue; |
| (...skipping 148 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 6004 Handle<FixedArray> constants = isolate()->factory()->empty_fixed_array(); | 5995 Handle<FixedArray> constants = isolate()->factory()->empty_fixed_array(); |
| 6005 int literal_index = expr->literal_index(); | 5996 int literal_index = expr->literal_index(); |
| 6006 int flags = expr->ComputeFlags(true); | 5997 int flags = expr->ComputeFlags(true); |
| 6007 | 5998 |
| 6008 Add<HPushArguments>(Add<HConstant>(literals), | 5999 Add<HPushArguments>(Add<HConstant>(literals), |
| 6009 Add<HConstant>(literal_index), | 6000 Add<HConstant>(literal_index), |
| 6010 Add<HConstant>(constants), | 6001 Add<HConstant>(constants), |
| 6011 Add<HConstant>(flags)); | 6002 Add<HConstant>(flags)); |
| 6012 | 6003 |
| 6013 Runtime::FunctionId function_id = Runtime::kCreateArrayLiteral; | 6004 Runtime::FunctionId function_id = Runtime::kCreateArrayLiteral; |
| 6014 literal = Add<HCallRuntime>(isolate()->factory()->empty_string(), | 6005 literal = Add<HCallRuntime>(Runtime::FunctionForId(function_id), 4); |
| 6015 Runtime::FunctionForId(function_id), | |
| 6016 4); | |
| 6017 | 6006 |
| 6018 // Register to deopt if the boilerplate ElementsKind changes. | 6007 // Register to deopt if the boilerplate ElementsKind changes. |
| 6019 top_info()->dependencies()->AssumeTransitionStable(site); | 6008 top_info()->dependencies()->AssumeTransitionStable(site); |
| 6020 } | 6009 } |
| 6021 | 6010 |
| 6022 // The array is expected in the bailout environment during computation | 6011 // The array is expected in the bailout environment during computation |
| 6023 // of the property values and is the value of the entire expression. | 6012 // of the property values and is the value of the entire expression. |
| 6024 Push(literal); | 6013 Push(literal); |
| 6025 // The literal index is on the stack, too. | 6014 // The literal index is on the stack, too. |
| 6026 Push(Add<HConstant>(expr->literal_index())); | 6015 Push(Add<HConstant>(expr->literal_index())); |
| (...skipping 468 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 6495 HValue* checked_holder = checked_object; | 6484 HValue* checked_holder = checked_object; |
| 6496 if (info->has_holder()) { | 6485 if (info->has_holder()) { |
| 6497 Handle<JSObject> prototype(JSObject::cast(info->map()->prototype())); | 6486 Handle<JSObject> prototype(JSObject::cast(info->map()->prototype())); |
| 6498 checked_holder = BuildCheckPrototypeMaps(prototype, info->holder()); | 6487 checked_holder = BuildCheckPrototypeMaps(prototype, info->holder()); |
| 6499 } | 6488 } |
| 6500 | 6489 |
| 6501 if (!info->IsFound()) { | 6490 if (!info->IsFound()) { |
| 6502 DCHECK(info->IsLoad()); | 6491 DCHECK(info->IsLoad()); |
| 6503 if (is_strong(function_language_mode())) { | 6492 if (is_strong(function_language_mode())) { |
| 6504 return New<HCallRuntime>( | 6493 return New<HCallRuntime>( |
| 6505 isolate()->factory()->empty_string(), | |
| 6506 Runtime::FunctionForId(Runtime::kThrowStrongModeImplicitConversion), | 6494 Runtime::FunctionForId(Runtime::kThrowStrongModeImplicitConversion), |
| 6507 0); | 6495 0); |
| 6508 } else { | 6496 } else { |
| 6509 return graph()->GetConstantUndefined(); | 6497 return graph()->GetConstantUndefined(); |
| 6510 } | 6498 } |
| 6511 } | 6499 } |
| 6512 | 6500 |
| 6513 if (info->IsData()) { | 6501 if (info->IsData()) { |
| 6514 if (info->IsLoad()) { | 6502 if (info->IsLoad()) { |
| 6515 return BuildLoadNamedField(info, checked_holder); | 6503 return BuildLoadNamedField(info, checked_holder); |
| (...skipping 635 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 7151 // The parser turns invalid left-hand sides in assignments into throw | 7139 // The parser turns invalid left-hand sides in assignments into throw |
| 7152 // statements, which may not be in effect contexts. We might still try | 7140 // statements, which may not be in effect contexts. We might still try |
| 7153 // to optimize such functions; bail out now if we do. | 7141 // to optimize such functions; bail out now if we do. |
| 7154 return Bailout(kInvalidLeftHandSideInAssignment); | 7142 return Bailout(kInvalidLeftHandSideInAssignment); |
| 7155 } | 7143 } |
| 7156 CHECK_ALIVE(VisitForValue(expr->exception())); | 7144 CHECK_ALIVE(VisitForValue(expr->exception())); |
| 7157 | 7145 |
| 7158 HValue* value = environment()->Pop(); | 7146 HValue* value = environment()->Pop(); |
| 7159 if (!top_info()->is_tracking_positions()) SetSourcePosition(expr->position()); | 7147 if (!top_info()->is_tracking_positions()) SetSourcePosition(expr->position()); |
| 7160 Add<HPushArguments>(value); | 7148 Add<HPushArguments>(value); |
| 7161 Add<HCallRuntime>(isolate()->factory()->empty_string(), | 7149 Add<HCallRuntime>(Runtime::FunctionForId(Runtime::kThrow), 1); |
| 7162 Runtime::FunctionForId(Runtime::kThrow), 1); | |
| 7163 Add<HSimulate>(expr->id()); | 7150 Add<HSimulate>(expr->id()); |
| 7164 | 7151 |
| 7165 // If the throw definitely exits the function, we can finish with a dummy | 7152 // If the throw definitely exits the function, we can finish with a dummy |
| 7166 // control flow at this point. This is not the case if the throw is inside | 7153 // control flow at this point. This is not the case if the throw is inside |
| 7167 // an inlined function which may be replaced. | 7154 // an inlined function which may be replaced. |
| 7168 if (call_context() == NULL) { | 7155 if (call_context() == NULL) { |
| 7169 FinishExitCurrentBlock(New<HAbnormalExit>()); | 7156 FinishExitCurrentBlock(New<HAbnormalExit>()); |
| 7170 } | 7157 } |
| 7171 } | 7158 } |
| 7172 | 7159 |
| (...skipping 3104 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 10277 if (!is_zero_byte_offset) { | 10264 if (!is_zero_byte_offset) { |
| 10278 byte_offset_smi.Else(); | 10265 byte_offset_smi.Else(); |
| 10279 { // byte_offset is not Smi. | 10266 { // byte_offset is not Smi. |
| 10280 Push(obj); | 10267 Push(obj); |
| 10281 CHECK_ALIVE(VisitForValue(arguments->at(kArrayIdArg))); | 10268 CHECK_ALIVE(VisitForValue(arguments->at(kArrayIdArg))); |
| 10282 Push(buffer); | 10269 Push(buffer); |
| 10283 Push(byte_offset); | 10270 Push(byte_offset); |
| 10284 Push(byte_length); | 10271 Push(byte_length); |
| 10285 CHECK_ALIVE(VisitForValue(arguments->at(kInitializeArg))); | 10272 CHECK_ALIVE(VisitForValue(arguments->at(kInitializeArg))); |
| 10286 PushArgumentsFromEnvironment(kArgsLength); | 10273 PushArgumentsFromEnvironment(kArgsLength); |
| 10287 Add<HCallRuntime>(expr->name(), expr->function(), kArgsLength); | 10274 Add<HCallRuntime>(expr->function(), kArgsLength); |
| 10288 } | 10275 } |
| 10289 } | 10276 } |
| 10290 byte_offset_smi.End(); | 10277 byte_offset_smi.End(); |
| 10291 } | 10278 } |
| 10292 | 10279 |
| 10293 | 10280 |
| 10294 void HOptimizedGraphBuilder::GenerateMaxSmi(CallRuntime* expr) { | 10281 void HOptimizedGraphBuilder::GenerateMaxSmi(CallRuntime* expr) { |
| 10295 DCHECK(expr->arguments()->length() == 0); | 10282 DCHECK(expr->arguments()->length() == 0); |
| 10296 HConstant* max_smi = New<HConstant>(static_cast<int32_t>(Smi::kMaxValue)); | 10283 HConstant* max_smi = New<HConstant>(static_cast<int32_t>(Smi::kMaxValue)); |
| 10297 return ast_context()->ReturnInstruction(max_smi, expr->id()); | 10284 return ast_context()->ReturnInstruction(max_smi, expr->id()); |
| (...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 10368 const Runtime::Function* function = expr->function(); | 10355 const Runtime::Function* function = expr->function(); |
| 10369 DCHECK(function != NULL); | 10356 DCHECK(function != NULL); |
| 10370 switch (function->function_id) { | 10357 switch (function->function_id) { |
| 10371 #define CALL_INTRINSIC_GENERATOR(Name) \ | 10358 #define CALL_INTRINSIC_GENERATOR(Name) \ |
| 10372 case Runtime::kInline##Name: \ | 10359 case Runtime::kInline##Name: \ |
| 10373 return Generate##Name(expr); | 10360 return Generate##Name(expr); |
| 10374 | 10361 |
| 10375 FOR_EACH_HYDROGEN_INTRINSIC(CALL_INTRINSIC_GENERATOR) | 10362 FOR_EACH_HYDROGEN_INTRINSIC(CALL_INTRINSIC_GENERATOR) |
| 10376 #undef CALL_INTRINSIC_GENERATOR | 10363 #undef CALL_INTRINSIC_GENERATOR |
| 10377 default: { | 10364 default: { |
| 10378 Handle<String> name = expr->name(); | |
| 10379 int argument_count = expr->arguments()->length(); | 10365 int argument_count = expr->arguments()->length(); |
| 10380 CHECK_ALIVE(VisitExpressions(expr->arguments())); | 10366 CHECK_ALIVE(VisitExpressions(expr->arguments())); |
| 10381 PushArgumentsFromEnvironment(argument_count); | 10367 PushArgumentsFromEnvironment(argument_count); |
| 10382 HCallRuntime* call = New<HCallRuntime>(name, function, argument_count); | 10368 HCallRuntime* call = New<HCallRuntime>(function, argument_count); |
| 10383 return ast_context()->ReturnInstruction(call, expr->id()); | 10369 return ast_context()->ReturnInstruction(call, expr->id()); |
| 10384 } | 10370 } |
| 10385 } | 10371 } |
| 10386 } | 10372 } |
| 10387 | 10373 |
| 10388 | 10374 |
| 10389 void HOptimizedGraphBuilder::VisitUnaryOperation(UnaryOperation* expr) { | 10375 void HOptimizedGraphBuilder::VisitUnaryOperation(UnaryOperation* expr) { |
| 10390 DCHECK(!HasStackOverflow()); | 10376 DCHECK(!HasStackOverflow()); |
| 10391 DCHECK(current_block() != NULL); | 10377 DCHECK(current_block() != NULL); |
| 10392 DCHECK(current_block()->HasPredecessor()); | 10378 DCHECK(current_block()->HasPredecessor()); |
| (...skipping 10 matching lines...) Expand all Loading... |
| 10403 void HOptimizedGraphBuilder::VisitDelete(UnaryOperation* expr) { | 10389 void HOptimizedGraphBuilder::VisitDelete(UnaryOperation* expr) { |
| 10404 Property* prop = expr->expression()->AsProperty(); | 10390 Property* prop = expr->expression()->AsProperty(); |
| 10405 VariableProxy* proxy = expr->expression()->AsVariableProxy(); | 10391 VariableProxy* proxy = expr->expression()->AsVariableProxy(); |
| 10406 if (prop != NULL) { | 10392 if (prop != NULL) { |
| 10407 CHECK_ALIVE(VisitForValue(prop->obj())); | 10393 CHECK_ALIVE(VisitForValue(prop->obj())); |
| 10408 CHECK_ALIVE(VisitForValue(prop->key())); | 10394 CHECK_ALIVE(VisitForValue(prop->key())); |
| 10409 HValue* key = Pop(); | 10395 HValue* key = Pop(); |
| 10410 HValue* obj = Pop(); | 10396 HValue* obj = Pop(); |
| 10411 Add<HPushArguments>(obj, key); | 10397 Add<HPushArguments>(obj, key); |
| 10412 HInstruction* instr = New<HCallRuntime>( | 10398 HInstruction* instr = New<HCallRuntime>( |
| 10413 isolate()->factory()->empty_string(), | |
| 10414 Runtime::FunctionForId(is_strict(function_language_mode()) | 10399 Runtime::FunctionForId(is_strict(function_language_mode()) |
| 10415 ? Runtime::kDeleteProperty_Strict | 10400 ? Runtime::kDeleteProperty_Strict |
| 10416 : Runtime::kDeleteProperty_Sloppy), | 10401 : Runtime::kDeleteProperty_Sloppy), |
| 10417 2); | 10402 2); |
| 10418 return ast_context()->ReturnInstruction(instr, expr->id()); | 10403 return ast_context()->ReturnInstruction(instr, expr->id()); |
| 10419 } else if (proxy != NULL) { | 10404 } else if (proxy != NULL) { |
| 10420 Variable* var = proxy->var(); | 10405 Variable* var = proxy->var(); |
| 10421 if (var->IsUnallocatedOrGlobalSlot()) { | 10406 if (var->IsUnallocatedOrGlobalSlot()) { |
| 10422 Bailout(kDeleteWithGlobalVariable); | 10407 Bailout(kDeleteWithGlobalVariable); |
| 10423 } else if (var->IsStackAllocated() || var->IsContextSlot()) { | 10408 } else if (var->IsStackAllocated() || var->IsContextSlot()) { |
| (...skipping 586 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 11010 } else { | 10995 } else { |
| 11011 if (is_strong(strength) && Token::IsBitOp(op)) { | 10996 if (is_strong(strength) && Token::IsBitOp(op)) { |
| 11012 // TODO(conradw): This is not efficient, but is necessary to prevent | 10997 // TODO(conradw): This is not efficient, but is necessary to prevent |
| 11013 // conversion of oddball values to numbers in strong mode. It would be | 10998 // conversion of oddball values to numbers in strong mode. It would be |
| 11014 // better to prevent the conversion rather than adding a runtime check. | 10999 // better to prevent the conversion rather than adding a runtime check. |
| 11015 IfBuilder if_builder(this); | 11000 IfBuilder if_builder(this); |
| 11016 if_builder.If<HHasInstanceTypeAndBranch>(left, ODDBALL_TYPE); | 11001 if_builder.If<HHasInstanceTypeAndBranch>(left, ODDBALL_TYPE); |
| 11017 if_builder.OrIf<HHasInstanceTypeAndBranch>(right, ODDBALL_TYPE); | 11002 if_builder.OrIf<HHasInstanceTypeAndBranch>(right, ODDBALL_TYPE); |
| 11018 if_builder.Then(); | 11003 if_builder.Then(); |
| 11019 Add<HCallRuntime>( | 11004 Add<HCallRuntime>( |
| 11020 isolate()->factory()->empty_string(), | |
| 11021 Runtime::FunctionForId(Runtime::kThrowStrongModeImplicitConversion), | 11005 Runtime::FunctionForId(Runtime::kThrowStrongModeImplicitConversion), |
| 11022 0); | 11006 0); |
| 11023 if (!graph()->info()->IsStub()) { | 11007 if (!graph()->info()->IsStub()) { |
| 11024 Add<HSimulate>(opt_id, REMOVABLE_SIMULATE); | 11008 Add<HSimulate>(opt_id, REMOVABLE_SIMULATE); |
| 11025 } | 11009 } |
| 11026 if_builder.End(); | 11010 if_builder.End(); |
| 11027 } | 11011 } |
| 11028 switch (op) { | 11012 switch (op) { |
| 11029 case Token::ADD: | 11013 case Token::ADD: |
| 11030 instr = AddUncasted<HAdd>(left, right, strength); | 11014 instr = AddUncasted<HAdd>(left, right, strength); |
| (...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 11108 | 11092 |
| 11109 | 11093 |
| 11110 // Check for the form (%_ClassOf(foo) === 'BarClass'). | 11094 // Check for the form (%_ClassOf(foo) === 'BarClass'). |
| 11111 static bool IsClassOfTest(CompareOperation* expr) { | 11095 static bool IsClassOfTest(CompareOperation* expr) { |
| 11112 if (expr->op() != Token::EQ_STRICT) return false; | 11096 if (expr->op() != Token::EQ_STRICT) return false; |
| 11113 CallRuntime* call = expr->left()->AsCallRuntime(); | 11097 CallRuntime* call = expr->left()->AsCallRuntime(); |
| 11114 if (call == NULL) return false; | 11098 if (call == NULL) return false; |
| 11115 Literal* literal = expr->right()->AsLiteral(); | 11099 Literal* literal = expr->right()->AsLiteral(); |
| 11116 if (literal == NULL) return false; | 11100 if (literal == NULL) return false; |
| 11117 if (!literal->value()->IsString()) return false; | 11101 if (!literal->value()->IsString()) return false; |
| 11118 if (!call->name()->IsOneByteEqualTo(STATIC_CHAR_VECTOR("_ClassOf"))) { | 11102 if (call->function()->function_id != Runtime::kInlineClassOf) return false; |
| 11119 return false; | |
| 11120 } | |
| 11121 DCHECK(call->arguments()->length() == 1); | 11103 DCHECK(call->arguments()->length() == 1); |
| 11122 return true; | 11104 return true; |
| 11123 } | 11105 } |
| 11124 | 11106 |
| 11125 | 11107 |
| 11126 void HOptimizedGraphBuilder::VisitBinaryOperation(BinaryOperation* expr) { | 11108 void HOptimizedGraphBuilder::VisitBinaryOperation(BinaryOperation* expr) { |
| 11127 DCHECK(!HasStackOverflow()); | 11109 DCHECK(!HasStackOverflow()); |
| 11128 DCHECK(current_block() != NULL); | 11110 DCHECK(current_block() != NULL); |
| 11129 DCHECK(current_block()->HasPredecessor()); | 11111 DCHECK(current_block()->HasPredecessor()); |
| 11130 switch (expr->op()) { | 11112 switch (expr->op()) { |
| (...skipping 1656 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 12787 { | 12769 { |
| 12788 IfBuilder needs_runtime(this); | 12770 IfBuilder needs_runtime(this); |
| 12789 needs_runtime.If<HCompareNumericAndBranch>( | 12771 needs_runtime.If<HCompareNumericAndBranch>( |
| 12790 is_access_check_needed_test, graph()->GetConstant0(), Token::NE); | 12772 is_access_check_needed_test, graph()->GetConstant0(), Token::NE); |
| 12791 needs_runtime.OrIf<HCompareNumericAndBranch>( | 12773 needs_runtime.OrIf<HCompareNumericAndBranch>( |
| 12792 is_hidden_prototype_test, graph()->GetConstant0(), Token::NE); | 12774 is_hidden_prototype_test, graph()->GetConstant0(), Token::NE); |
| 12793 | 12775 |
| 12794 needs_runtime.Then(); | 12776 needs_runtime.Then(); |
| 12795 { | 12777 { |
| 12796 Add<HPushArguments>(object); | 12778 Add<HPushArguments>(object); |
| 12797 Push(Add<HCallRuntime>( | 12779 Push( |
| 12798 call->name(), Runtime::FunctionForId(Runtime::kGetPrototype), 1)); | 12780 Add<HCallRuntime>(Runtime::FunctionForId(Runtime::kGetPrototype), 1)); |
| 12799 } | 12781 } |
| 12800 | 12782 |
| 12801 needs_runtime.Else(); | 12783 needs_runtime.Else(); |
| 12802 Push(proto); | 12784 Push(proto); |
| 12803 } | 12785 } |
| 12804 return ast_context()->ReturnValue(Pop()); | 12786 return ast_context()->ReturnValue(Pop()); |
| 12805 } | 12787 } |
| 12806 | 12788 |
| 12807 | 12789 |
| 12808 #undef CHECK_BAILOUT | 12790 #undef CHECK_BAILOUT |
| (...skipping 623 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 13432 isolate()->GetHTracer()->TraceHydrogen(name(), graph_); | 13414 isolate()->GetHTracer()->TraceHydrogen(name(), graph_); |
| 13433 } | 13415 } |
| 13434 | 13416 |
| 13435 #ifdef DEBUG | 13417 #ifdef DEBUG |
| 13436 graph_->Verify(false); // No full verify. | 13418 graph_->Verify(false); // No full verify. |
| 13437 #endif | 13419 #endif |
| 13438 } | 13420 } |
| 13439 | 13421 |
| 13440 } // namespace internal | 13422 } // namespace internal |
| 13441 } // namespace v8 | 13423 } // namespace v8 |
| OLD | NEW |