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; |
Michael Starzinger
2015/08/26 09:43:21
Is "call" guaranteed to point to a runtime functio
Yang
2015/08/26 10:27:30
Done.
| |
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 |