| 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 3105 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 10278 if (!is_zero_byte_offset) { | 10265 if (!is_zero_byte_offset) { |
| 10279 byte_offset_smi.Else(); | 10266 byte_offset_smi.Else(); |
| 10280 { // byte_offset is not Smi. | 10267 { // byte_offset is not Smi. |
| 10281 Push(obj); | 10268 Push(obj); |
| 10282 CHECK_ALIVE(VisitForValue(arguments->at(kArrayIdArg))); | 10269 CHECK_ALIVE(VisitForValue(arguments->at(kArrayIdArg))); |
| 10283 Push(buffer); | 10270 Push(buffer); |
| 10284 Push(byte_offset); | 10271 Push(byte_offset); |
| 10285 Push(byte_length); | 10272 Push(byte_length); |
| 10286 CHECK_ALIVE(VisitForValue(arguments->at(kInitializeArg))); | 10273 CHECK_ALIVE(VisitForValue(arguments->at(kInitializeArg))); |
| 10287 PushArgumentsFromEnvironment(kArgsLength); | 10274 PushArgumentsFromEnvironment(kArgsLength); |
| 10288 Add<HCallRuntime>(expr->name(), expr->function(), kArgsLength); | 10275 Add<HCallRuntime>(expr->function(), kArgsLength); |
| 10289 } | 10276 } |
| 10290 } | 10277 } |
| 10291 byte_offset_smi.End(); | 10278 byte_offset_smi.End(); |
| 10292 } | 10279 } |
| 10293 | 10280 |
| 10294 | 10281 |
| 10295 void HOptimizedGraphBuilder::GenerateMaxSmi(CallRuntime* expr) { | 10282 void HOptimizedGraphBuilder::GenerateMaxSmi(CallRuntime* expr) { |
| 10296 DCHECK(expr->arguments()->length() == 0); | 10283 DCHECK(expr->arguments()->length() == 0); |
| 10297 HConstant* max_smi = New<HConstant>(static_cast<int32_t>(Smi::kMaxValue)); | 10284 HConstant* max_smi = New<HConstant>(static_cast<int32_t>(Smi::kMaxValue)); |
| 10298 return ast_context()->ReturnInstruction(max_smi, expr->id()); | 10285 return ast_context()->ReturnInstruction(max_smi, expr->id()); |
| (...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 10369 const Runtime::Function* function = expr->function(); | 10356 const Runtime::Function* function = expr->function(); |
| 10370 DCHECK(function != NULL); | 10357 DCHECK(function != NULL); |
| 10371 switch (function->function_id) { | 10358 switch (function->function_id) { |
| 10372 #define CALL_INTRINSIC_GENERATOR(Name) \ | 10359 #define CALL_INTRINSIC_GENERATOR(Name) \ |
| 10373 case Runtime::kInline##Name: \ | 10360 case Runtime::kInline##Name: \ |
| 10374 return Generate##Name(expr); | 10361 return Generate##Name(expr); |
| 10375 | 10362 |
| 10376 FOR_EACH_HYDROGEN_INTRINSIC(CALL_INTRINSIC_GENERATOR) | 10363 FOR_EACH_HYDROGEN_INTRINSIC(CALL_INTRINSIC_GENERATOR) |
| 10377 #undef CALL_INTRINSIC_GENERATOR | 10364 #undef CALL_INTRINSIC_GENERATOR |
| 10378 default: { | 10365 default: { |
| 10379 Handle<String> name = expr->name(); | |
| 10380 int argument_count = expr->arguments()->length(); | 10366 int argument_count = expr->arguments()->length(); |
| 10381 CHECK_ALIVE(VisitExpressions(expr->arguments())); | 10367 CHECK_ALIVE(VisitExpressions(expr->arguments())); |
| 10382 PushArgumentsFromEnvironment(argument_count); | 10368 PushArgumentsFromEnvironment(argument_count); |
| 10383 HCallRuntime* call = New<HCallRuntime>(name, function, argument_count); | 10369 HCallRuntime* call = New<HCallRuntime>(function, argument_count); |
| 10384 return ast_context()->ReturnInstruction(call, expr->id()); | 10370 return ast_context()->ReturnInstruction(call, expr->id()); |
| 10385 } | 10371 } |
| 10386 } | 10372 } |
| 10387 } | 10373 } |
| 10388 | 10374 |
| 10389 | 10375 |
| 10390 void HOptimizedGraphBuilder::VisitUnaryOperation(UnaryOperation* expr) { | 10376 void HOptimizedGraphBuilder::VisitUnaryOperation(UnaryOperation* expr) { |
| 10391 DCHECK(!HasStackOverflow()); | 10377 DCHECK(!HasStackOverflow()); |
| 10392 DCHECK(current_block() != NULL); | 10378 DCHECK(current_block() != NULL); |
| 10393 DCHECK(current_block()->HasPredecessor()); | 10379 DCHECK(current_block()->HasPredecessor()); |
| (...skipping 10 matching lines...) Expand all Loading... |
| 10404 void HOptimizedGraphBuilder::VisitDelete(UnaryOperation* expr) { | 10390 void HOptimizedGraphBuilder::VisitDelete(UnaryOperation* expr) { |
| 10405 Property* prop = expr->expression()->AsProperty(); | 10391 Property* prop = expr->expression()->AsProperty(); |
| 10406 VariableProxy* proxy = expr->expression()->AsVariableProxy(); | 10392 VariableProxy* proxy = expr->expression()->AsVariableProxy(); |
| 10407 if (prop != NULL) { | 10393 if (prop != NULL) { |
| 10408 CHECK_ALIVE(VisitForValue(prop->obj())); | 10394 CHECK_ALIVE(VisitForValue(prop->obj())); |
| 10409 CHECK_ALIVE(VisitForValue(prop->key())); | 10395 CHECK_ALIVE(VisitForValue(prop->key())); |
| 10410 HValue* key = Pop(); | 10396 HValue* key = Pop(); |
| 10411 HValue* obj = Pop(); | 10397 HValue* obj = Pop(); |
| 10412 Add<HPushArguments>(obj, key); | 10398 Add<HPushArguments>(obj, key); |
| 10413 HInstruction* instr = New<HCallRuntime>( | 10399 HInstruction* instr = New<HCallRuntime>( |
| 10414 isolate()->factory()->empty_string(), | |
| 10415 Runtime::FunctionForId(is_strict(function_language_mode()) | 10400 Runtime::FunctionForId(is_strict(function_language_mode()) |
| 10416 ? Runtime::kDeleteProperty_Strict | 10401 ? Runtime::kDeleteProperty_Strict |
| 10417 : Runtime::kDeleteProperty_Sloppy), | 10402 : Runtime::kDeleteProperty_Sloppy), |
| 10418 2); | 10403 2); |
| 10419 return ast_context()->ReturnInstruction(instr, expr->id()); | 10404 return ast_context()->ReturnInstruction(instr, expr->id()); |
| 10420 } else if (proxy != NULL) { | 10405 } else if (proxy != NULL) { |
| 10421 Variable* var = proxy->var(); | 10406 Variable* var = proxy->var(); |
| 10422 if (var->IsUnallocatedOrGlobalSlot()) { | 10407 if (var->IsUnallocatedOrGlobalSlot()) { |
| 10423 Bailout(kDeleteWithGlobalVariable); | 10408 Bailout(kDeleteWithGlobalVariable); |
| 10424 } else if (var->IsStackAllocated() || var->IsContextSlot()) { | 10409 } else if (var->IsStackAllocated() || var->IsContextSlot()) { |
| (...skipping 586 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 11011 } else { | 10996 } else { |
| 11012 if (is_strong(strength) && Token::IsBitOp(op)) { | 10997 if (is_strong(strength) && Token::IsBitOp(op)) { |
| 11013 // TODO(conradw): This is not efficient, but is necessary to prevent | 10998 // TODO(conradw): This is not efficient, but is necessary to prevent |
| 11014 // conversion of oddball values to numbers in strong mode. It would be | 10999 // conversion of oddball values to numbers in strong mode. It would be |
| 11015 // better to prevent the conversion rather than adding a runtime check. | 11000 // better to prevent the conversion rather than adding a runtime check. |
| 11016 IfBuilder if_builder(this); | 11001 IfBuilder if_builder(this); |
| 11017 if_builder.If<HHasInstanceTypeAndBranch>(left, ODDBALL_TYPE); | 11002 if_builder.If<HHasInstanceTypeAndBranch>(left, ODDBALL_TYPE); |
| 11018 if_builder.OrIf<HHasInstanceTypeAndBranch>(right, ODDBALL_TYPE); | 11003 if_builder.OrIf<HHasInstanceTypeAndBranch>(right, ODDBALL_TYPE); |
| 11019 if_builder.Then(); | 11004 if_builder.Then(); |
| 11020 Add<HCallRuntime>( | 11005 Add<HCallRuntime>( |
| 11021 isolate()->factory()->empty_string(), | |
| 11022 Runtime::FunctionForId(Runtime::kThrowStrongModeImplicitConversion), | 11006 Runtime::FunctionForId(Runtime::kThrowStrongModeImplicitConversion), |
| 11023 0); | 11007 0); |
| 11024 if (!graph()->info()->IsStub()) { | 11008 if (!graph()->info()->IsStub()) { |
| 11025 Add<HSimulate>(opt_id, REMOVABLE_SIMULATE); | 11009 Add<HSimulate>(opt_id, REMOVABLE_SIMULATE); |
| 11026 } | 11010 } |
| 11027 if_builder.End(); | 11011 if_builder.End(); |
| 11028 } | 11012 } |
| 11029 switch (op) { | 11013 switch (op) { |
| 11030 case Token::ADD: | 11014 case Token::ADD: |
| 11031 instr = AddUncasted<HAdd>(left, right, strength); | 11015 instr = AddUncasted<HAdd>(left, right, strength); |
| (...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 11109 | 11093 |
| 11110 | 11094 |
| 11111 // Check for the form (%_ClassOf(foo) === 'BarClass'). | 11095 // Check for the form (%_ClassOf(foo) === 'BarClass'). |
| 11112 static bool IsClassOfTest(CompareOperation* expr) { | 11096 static bool IsClassOfTest(CompareOperation* expr) { |
| 11113 if (expr->op() != Token::EQ_STRICT) return false; | 11097 if (expr->op() != Token::EQ_STRICT) return false; |
| 11114 CallRuntime* call = expr->left()->AsCallRuntime(); | 11098 CallRuntime* call = expr->left()->AsCallRuntime(); |
| 11115 if (call == NULL) return false; | 11099 if (call == NULL) return false; |
| 11116 Literal* literal = expr->right()->AsLiteral(); | 11100 Literal* literal = expr->right()->AsLiteral(); |
| 11117 if (literal == NULL) return false; | 11101 if (literal == NULL) return false; |
| 11118 if (!literal->value()->IsString()) return false; | 11102 if (!literal->value()->IsString()) return false; |
| 11119 if (!call->name()->IsOneByteEqualTo(STATIC_CHAR_VECTOR("_ClassOf"))) { | 11103 if (!call->is_jsruntime() && |
| 11104 call->function()->function_id != Runtime::kInlineClassOf) { |
| 11120 return false; | 11105 return false; |
| 11121 } | 11106 } |
| 11122 DCHECK(call->arguments()->length() == 1); | 11107 DCHECK(call->arguments()->length() == 1); |
| 11123 return true; | 11108 return true; |
| 11124 } | 11109 } |
| 11125 | 11110 |
| 11126 | 11111 |
| 11127 void HOptimizedGraphBuilder::VisitBinaryOperation(BinaryOperation* expr) { | 11112 void HOptimizedGraphBuilder::VisitBinaryOperation(BinaryOperation* expr) { |
| 11128 DCHECK(!HasStackOverflow()); | 11113 DCHECK(!HasStackOverflow()); |
| 11129 DCHECK(current_block() != NULL); | 11114 DCHECK(current_block() != NULL); |
| (...skipping 1683 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 12813 { | 12798 { |
| 12814 IfBuilder needs_runtime(this); | 12799 IfBuilder needs_runtime(this); |
| 12815 needs_runtime.If<HCompareNumericAndBranch>( | 12800 needs_runtime.If<HCompareNumericAndBranch>( |
| 12816 is_access_check_needed_test, graph()->GetConstant0(), Token::NE); | 12801 is_access_check_needed_test, graph()->GetConstant0(), Token::NE); |
| 12817 needs_runtime.OrIf<HCompareNumericAndBranch>( | 12802 needs_runtime.OrIf<HCompareNumericAndBranch>( |
| 12818 is_hidden_prototype_test, graph()->GetConstant0(), Token::NE); | 12803 is_hidden_prototype_test, graph()->GetConstant0(), Token::NE); |
| 12819 | 12804 |
| 12820 needs_runtime.Then(); | 12805 needs_runtime.Then(); |
| 12821 { | 12806 { |
| 12822 Add<HPushArguments>(object); | 12807 Add<HPushArguments>(object); |
| 12823 Push(Add<HCallRuntime>( | 12808 Push( |
| 12824 call->name(), Runtime::FunctionForId(Runtime::kGetPrototype), 1)); | 12809 Add<HCallRuntime>(Runtime::FunctionForId(Runtime::kGetPrototype), 1)); |
| 12825 } | 12810 } |
| 12826 | 12811 |
| 12827 needs_runtime.Else(); | 12812 needs_runtime.Else(); |
| 12828 Push(proto); | 12813 Push(proto); |
| 12829 } | 12814 } |
| 12830 return ast_context()->ReturnValue(Pop()); | 12815 return ast_context()->ReturnValue(Pop()); |
| 12831 } | 12816 } |
| 12832 | 12817 |
| 12833 | 12818 |
| 12834 #undef CHECK_BAILOUT | 12819 #undef CHECK_BAILOUT |
| (...skipping 623 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 13458 isolate()->GetHTracer()->TraceHydrogen(name(), graph_); | 13443 isolate()->GetHTracer()->TraceHydrogen(name(), graph_); |
| 13459 } | 13444 } |
| 13460 | 13445 |
| 13461 #ifdef DEBUG | 13446 #ifdef DEBUG |
| 13462 graph_->Verify(false); // No full verify. | 13447 graph_->Verify(false); // No full verify. |
| 13463 #endif | 13448 #endif |
| 13464 } | 13449 } |
| 13465 | 13450 |
| 13466 } // namespace internal | 13451 } // namespace internal |
| 13467 } // namespace v8 | 13452 } // namespace v8 |
| OLD | NEW |