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 |