OLD | NEW |
1 // Copyright 2013 the V8 project authors. All rights reserved. | 1 // Copyright 2013 the V8 project authors. All rights reserved. |
2 // Redistribution and use in source and binary forms, with or without | 2 // Redistribution and use in source and binary forms, with or without |
3 // modification, are permitted provided that the following conditions are | 3 // modification, are permitted provided that the following conditions are |
4 // met: | 4 // met: |
5 // | 5 // |
6 // * Redistributions of source code must retain the above copyright | 6 // * Redistributions of source code must retain the above copyright |
7 // notice, this list of conditions and the following disclaimer. | 7 // notice, this list of conditions and the following disclaimer. |
8 // * Redistributions in binary form must reproduce the above | 8 // * Redistributions in binary form must reproduce the above |
9 // copyright notice, this list of conditions and the following | 9 // copyright notice, this list of conditions and the following |
10 // disclaimer in the documentation and/or other materials provided | 10 // disclaimer in the documentation and/or other materials provided |
(...skipping 1185 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1196 return Add<HWrapReceiver>(object, function); | 1196 return Add<HWrapReceiver>(object, function); |
1197 } | 1197 } |
1198 | 1198 |
1199 | 1199 |
1200 HValue* HGraphBuilder::BuildCheckForCapacityGrow(HValue* object, | 1200 HValue* HGraphBuilder::BuildCheckForCapacityGrow(HValue* object, |
1201 HValue* elements, | 1201 HValue* elements, |
1202 ElementsKind kind, | 1202 ElementsKind kind, |
1203 HValue* length, | 1203 HValue* length, |
1204 HValue* key, | 1204 HValue* key, |
1205 bool is_js_array) { | 1205 bool is_js_array) { |
1206 Zone* zone = this->zone(); | |
1207 IfBuilder length_checker(this); | 1206 IfBuilder length_checker(this); |
1208 | 1207 |
1209 Token::Value token = IsHoleyElementsKind(kind) ? Token::GTE : Token::EQ; | 1208 Token::Value token = IsHoleyElementsKind(kind) ? Token::GTE : Token::EQ; |
1210 length_checker.If<HCompareNumericAndBranch>(key, length, token); | 1209 length_checker.If<HCompareNumericAndBranch>(key, length, token); |
1211 | 1210 |
1212 length_checker.Then(); | 1211 length_checker.Then(); |
1213 | 1212 |
1214 HValue* current_capacity = AddLoadFixedArrayLength(elements); | 1213 HValue* current_capacity = AddLoadFixedArrayLength(elements); |
1215 | 1214 |
1216 IfBuilder capacity_checker(this); | 1215 IfBuilder capacity_checker(this); |
1217 | 1216 |
1218 capacity_checker.If<HCompareNumericAndBranch>(key, current_capacity, | 1217 capacity_checker.If<HCompareNumericAndBranch>(key, current_capacity, |
1219 Token::GTE); | 1218 Token::GTE); |
1220 capacity_checker.Then(); | 1219 capacity_checker.Then(); |
1221 | 1220 |
1222 HValue* context = environment()->context(); | |
1223 | |
1224 HValue* max_gap = Add<HConstant>(static_cast<int32_t>(JSObject::kMaxGap)); | 1221 HValue* max_gap = Add<HConstant>(static_cast<int32_t>(JSObject::kMaxGap)); |
1225 HValue* max_capacity = Add<HAdd>(current_capacity, max_gap); | 1222 HValue* max_capacity = Add<HAdd>(current_capacity, max_gap); |
1226 IfBuilder key_checker(this); | 1223 IfBuilder key_checker(this); |
1227 key_checker.If<HCompareNumericAndBranch>(key, max_capacity, Token::LT); | 1224 key_checker.If<HCompareNumericAndBranch>(key, max_capacity, Token::LT); |
1228 key_checker.Then(); | 1225 key_checker.Then(); |
1229 key_checker.ElseDeopt("Key out of capacity range"); | 1226 key_checker.ElseDeopt("Key out of capacity range"); |
1230 key_checker.End(); | 1227 key_checker.End(); |
1231 | 1228 |
1232 HValue* new_capacity = BuildNewElementsCapacity(key); | 1229 HValue* new_capacity = BuildNewElementsCapacity(key); |
1233 HValue* new_elements = BuildGrowElementsCapacity(object, elements, | 1230 HValue* new_elements = BuildGrowElementsCapacity(object, elements, |
1234 kind, kind, length, | 1231 kind, kind, length, |
1235 new_capacity); | 1232 new_capacity); |
1236 | 1233 |
1237 environment()->Push(new_elements); | 1234 environment()->Push(new_elements); |
1238 capacity_checker.Else(); | 1235 capacity_checker.Else(); |
1239 | 1236 |
1240 environment()->Push(elements); | 1237 environment()->Push(elements); |
1241 capacity_checker.End(); | 1238 capacity_checker.End(); |
1242 | 1239 |
1243 if (is_js_array) { | 1240 if (is_js_array) { |
1244 HValue* new_length = AddInstruction( | 1241 HValue* new_length = AddUncasted<HAdd>(key, graph_->GetConstant1()); |
1245 HAdd::New(zone, context, key, graph_->GetConstant1())); | |
1246 new_length->ClearFlag(HValue::kCanOverflow); | 1242 new_length->ClearFlag(HValue::kCanOverflow); |
1247 | 1243 |
1248 Add<HStoreNamedField>(object, HObjectAccess::ForArrayLength(kind), | 1244 Add<HStoreNamedField>(object, HObjectAccess::ForArrayLength(kind), |
1249 new_length); | 1245 new_length); |
1250 } | 1246 } |
1251 | 1247 |
1252 length_checker.Else(); | 1248 length_checker.Else(); |
1253 Add<HBoundsCheck>(key, length); | 1249 Add<HBoundsCheck>(key, length); |
1254 | 1250 |
1255 environment()->Push(elements); | 1251 environment()->Push(elements); |
(...skipping 770 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2026 allocation_site_payload_(NULL), | 2022 allocation_site_payload_(NULL), |
2027 constructor_function_(constructor_function) { | 2023 constructor_function_(constructor_function) { |
2028 } | 2024 } |
2029 | 2025 |
2030 | 2026 |
2031 HValue* HGraphBuilder::JSArrayBuilder::EmitMapCode() { | 2027 HValue* HGraphBuilder::JSArrayBuilder::EmitMapCode() { |
2032 if (kind_ == GetInitialFastElementsKind()) { | 2028 if (kind_ == GetInitialFastElementsKind()) { |
2033 // No need for a context lookup if the kind_ matches the initial | 2029 // No need for a context lookup if the kind_ matches the initial |
2034 // map, because we can just load the map in that case. | 2030 // map, because we can just load the map in that case. |
2035 HObjectAccess access = HObjectAccess::ForPrototypeOrInitialMap(); | 2031 HObjectAccess access = HObjectAccess::ForPrototypeOrInitialMap(); |
2036 return builder()->AddInstruction( | 2032 return builder()->AddLoadNamedField(constructor_function_, access); |
2037 builder()->BuildLoadNamedField(constructor_function_, access)); | |
2038 } | 2033 } |
2039 | 2034 |
2040 HInstruction* native_context = builder()->BuildGetNativeContext(); | 2035 HInstruction* native_context = builder()->BuildGetNativeContext(); |
2041 HInstruction* index = builder()->Add<HConstant>( | 2036 HInstruction* index = builder()->Add<HConstant>( |
2042 static_cast<int32_t>(Context::JS_ARRAY_MAPS_INDEX)); | 2037 static_cast<int32_t>(Context::JS_ARRAY_MAPS_INDEX)); |
2043 | 2038 |
2044 HInstruction* map_array = builder()->Add<HLoadKeyed>( | 2039 HInstruction* map_array = builder()->Add<HLoadKeyed>( |
2045 native_context, index, static_cast<HValue*>(NULL), FAST_ELEMENTS); | 2040 native_context, index, static_cast<HValue*>(NULL), FAST_ELEMENTS); |
2046 | 2041 |
2047 HInstruction* kind_index = builder()->Add<HConstant>(kind_); | 2042 HInstruction* kind_index = builder()->Add<HConstant>(kind_); |
2048 | 2043 |
2049 return builder()->Add<HLoadKeyed>( | 2044 return builder()->Add<HLoadKeyed>( |
2050 map_array, kind_index, static_cast<HValue*>(NULL), FAST_ELEMENTS); | 2045 map_array, kind_index, static_cast<HValue*>(NULL), FAST_ELEMENTS); |
2051 } | 2046 } |
2052 | 2047 |
2053 | 2048 |
2054 HValue* HGraphBuilder::JSArrayBuilder::EmitInternalMapCode() { | 2049 HValue* HGraphBuilder::JSArrayBuilder::EmitInternalMapCode() { |
2055 // Find the map near the constructor function | 2050 // Find the map near the constructor function |
2056 HObjectAccess access = HObjectAccess::ForPrototypeOrInitialMap(); | 2051 HObjectAccess access = HObjectAccess::ForPrototypeOrInitialMap(); |
2057 return builder()->AddInstruction( | 2052 return builder()->AddLoadNamedField(constructor_function_, access); |
2058 builder()->BuildLoadNamedField(constructor_function_, access)); | |
2059 } | 2053 } |
2060 | 2054 |
2061 | 2055 |
2062 HValue* HGraphBuilder::JSArrayBuilder::EstablishAllocationSize( | 2056 HValue* HGraphBuilder::JSArrayBuilder::EstablishAllocationSize( |
2063 HValue* length_node) { | 2057 HValue* length_node) { |
2064 ASSERT(length_node != NULL); | 2058 ASSERT(length_node != NULL); |
2065 | 2059 |
2066 int base_size = JSArray::kSize; | 2060 int base_size = JSArray::kSize; |
2067 if (mode_ == TRACK_ALLOCATION_SITE) { | 2061 if (mode_ == TRACK_ALLOCATION_SITE) { |
2068 base_size += AllocationMemento::kSize; | 2062 base_size += AllocationMemento::kSize; |
(...skipping 2035 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4104 cell->AddDependentCompilationInfo(top_info()); | 4098 cell->AddDependentCompilationInfo(top_info()); |
4105 Handle<Object> constant_object = cell->type()->AsConstant(); | 4099 Handle<Object> constant_object = cell->type()->AsConstant(); |
4106 if (constant_object->IsConsString()) { | 4100 if (constant_object->IsConsString()) { |
4107 constant_object = | 4101 constant_object = |
4108 FlattenGetString(Handle<String>::cast(constant_object)); | 4102 FlattenGetString(Handle<String>::cast(constant_object)); |
4109 } | 4103 } |
4110 HConstant* constant = New<HConstant>(constant_object); | 4104 HConstant* constant = New<HConstant>(constant_object); |
4111 return ast_context()->ReturnInstruction(constant, expr->id()); | 4105 return ast_context()->ReturnInstruction(constant, expr->id()); |
4112 } else { | 4106 } else { |
4113 HLoadGlobalCell* instr = | 4107 HLoadGlobalCell* instr = |
4114 new(zone()) HLoadGlobalCell(cell, lookup.GetPropertyDetails()); | 4108 New<HLoadGlobalCell>(cell, lookup.GetPropertyDetails()); |
4115 return ast_context()->ReturnInstruction(instr, expr->id()); | 4109 return ast_context()->ReturnInstruction(instr, expr->id()); |
4116 } | 4110 } |
4117 } else { | 4111 } else { |
4118 HValue* context = environment()->context(); | 4112 HGlobalObject* global_object = Add<HGlobalObject>(); |
4119 HGlobalObject* global_object = new(zone()) HGlobalObject(context); | |
4120 AddInstruction(global_object); | |
4121 HLoadGlobalGeneric* instr = | 4113 HLoadGlobalGeneric* instr = |
4122 new(zone()) HLoadGlobalGeneric(context, | 4114 New<HLoadGlobalGeneric>(global_object, |
4123 global_object, | 4115 variable->name(), |
4124 variable->name(), | 4116 ast_context()->is_for_typeof()); |
4125 ast_context()->is_for_typeof()); | |
4126 return ast_context()->ReturnInstruction(instr, expr->id()); | 4117 return ast_context()->ReturnInstruction(instr, expr->id()); |
4127 } | 4118 } |
4128 } | 4119 } |
4129 | 4120 |
4130 case Variable::PARAMETER: | 4121 case Variable::PARAMETER: |
4131 case Variable::LOCAL: { | 4122 case Variable::LOCAL: { |
4132 HValue* value = LookupAndMakeLive(variable); | 4123 HValue* value = LookupAndMakeLive(variable); |
4133 if (value == graph()->GetConstantHole()) { | 4124 if (value == graph()->GetConstantHole()) { |
4134 ASSERT(IsDeclaredVariableMode(variable->mode()) && | 4125 ASSERT(IsDeclaredVariableMode(variable->mode()) && |
4135 variable->mode() != VAR); | 4126 variable->mode() != VAR); |
(...skipping 514 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4650 instr->SetGVNFlag(kChangesMaps); | 4641 instr->SetGVNFlag(kChangesMaps); |
4651 } | 4642 } |
4652 return instr; | 4643 return instr; |
4653 } | 4644 } |
4654 | 4645 |
4655 | 4646 |
4656 HInstruction* HOptimizedGraphBuilder::BuildStoreNamedGeneric( | 4647 HInstruction* HOptimizedGraphBuilder::BuildStoreNamedGeneric( |
4657 HValue* object, | 4648 HValue* object, |
4658 Handle<String> name, | 4649 Handle<String> name, |
4659 HValue* value) { | 4650 HValue* value) { |
4660 HValue* context = environment()->context(); | 4651 return New<HStoreNamedGeneric>( |
4661 return new(zone()) HStoreNamedGeneric( | |
4662 context, | |
4663 object, | 4652 object, |
4664 name, | 4653 name, |
4665 value, | 4654 value, |
4666 function_strict_mode_flag()); | 4655 function_strict_mode_flag()); |
4667 } | 4656 } |
4668 | 4657 |
4669 | 4658 |
4670 // Sets the lookup result and returns true if the load/store can be inlined. | 4659 // Sets the lookup result and returns true if the load/store can be inlined. |
4671 static bool ComputeStoreField(Handle<Map> type, | 4660 static bool ComputeStoreField(Handle<Map> type, |
4672 Handle<String> name, | 4661 Handle<String> name, |
(...skipping 244 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4917 // Finish up. Unconditionally deoptimize if we've handled all the maps we | 4906 // Finish up. Unconditionally deoptimize if we've handled all the maps we |
4918 // know about and do not want to handle ones we've never seen. Otherwise | 4907 // know about and do not want to handle ones we've never seen. Otherwise |
4919 // use a generic IC. | 4908 // use a generic IC. |
4920 if (count == types->length() && FLAG_deoptimize_uncommon_cases) { | 4909 if (count == types->length() && FLAG_deoptimize_uncommon_cases) { |
4921 // Because the deopt may be the only path in the polymorphic load, make sure | 4910 // Because the deopt may be the only path in the polymorphic load, make sure |
4922 // that the environment stack matches the depth on deopt that it otherwise | 4911 // that the environment stack matches the depth on deopt that it otherwise |
4923 // would have had after a successful load. | 4912 // would have had after a successful load. |
4924 if (!ast_context()->IsEffect()) Push(graph()->GetConstant0()); | 4913 if (!ast_context()->IsEffect()) Push(graph()->GetConstant0()); |
4925 FinishExitWithHardDeoptimization("Unknown map in polymorphic load", join); | 4914 FinishExitWithHardDeoptimization("Unknown map in polymorphic load", join); |
4926 } else { | 4915 } else { |
4927 HValue* context = environment()->context(); | 4916 HInstruction* load = Add<HLoadNamedGeneric>(object, name); |
4928 HInstruction* load = new(zone()) HLoadNamedGeneric(context, object, name); | |
4929 AddInstruction(load); | |
4930 if (!ast_context()->IsEffect()) Push(load); | 4917 if (!ast_context()->IsEffect()) Push(load); |
4931 | 4918 |
4932 if (join != NULL) { | 4919 if (join != NULL) { |
4933 Goto(join); | 4920 Goto(join); |
4934 } else { | 4921 } else { |
4935 Add<HSimulate>(ast_id, REMOVABLE_SIMULATE); | 4922 Add<HSimulate>(ast_id, REMOVABLE_SIMULATE); |
4936 if (!ast_context()->IsEffect()) ast_context()->ReturnValue(Pop()); | 4923 if (!ast_context()->IsEffect()) ast_context()->ReturnValue(Pop()); |
4937 return; | 4924 return; |
4938 } | 4925 } |
4939 } | 4926 } |
(...skipping 545 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5485 | 5472 |
5486 HValue* value = environment()->Pop(); | 5473 HValue* value = environment()->Pop(); |
5487 if (!FLAG_emit_opt_code_positions) SetSourcePosition(expr->position()); | 5474 if (!FLAG_emit_opt_code_positions) SetSourcePosition(expr->position()); |
5488 Add<HThrow>(value); | 5475 Add<HThrow>(value); |
5489 Add<HSimulate>(expr->id()); | 5476 Add<HSimulate>(expr->id()); |
5490 | 5477 |
5491 // If the throw definitely exits the function, we can finish with a dummy | 5478 // If the throw definitely exits the function, we can finish with a dummy |
5492 // control flow at this point. This is not the case if the throw is inside | 5479 // control flow at this point. This is not the case if the throw is inside |
5493 // an inlined function which may be replaced. | 5480 // an inlined function which may be replaced. |
5494 if (call_context() == NULL) { | 5481 if (call_context() == NULL) { |
5495 FinishExitCurrentBlock(new(zone()) HAbnormalExit); | 5482 FinishExitCurrentBlock(New<HAbnormalExit>()); |
5496 } | 5483 } |
5497 } | 5484 } |
5498 | 5485 |
5499 | 5486 |
5500 HLoadNamedField* HGraphBuilder::BuildLoadNamedField(HValue* object, | 5487 HLoadNamedField* HGraphBuilder::BuildLoadNamedField(HValue* object, |
5501 HObjectAccess access) { | 5488 HObjectAccess access) { |
5502 if (FLAG_track_double_fields && access.representation().IsDouble()) { | 5489 if (FLAG_track_double_fields && access.representation().IsDouble()) { |
5503 // load the heap number | 5490 // load the heap number |
5504 HLoadNamedField* heap_number = Add<HLoadNamedField>( | 5491 HLoadNamedField* heap_number = Add<HLoadNamedField>( |
5505 object, access.WithRepresentation(Representation::Tagged())); | 5492 object, access.WithRepresentation(Representation::Tagged())); |
5506 heap_number->set_type(HType::HeapNumber()); | 5493 heap_number->set_type(HType::HeapNumber()); |
5507 // load the double value from it | 5494 // load the double value from it |
5508 return New<HLoadNamedField>( | 5495 return New<HLoadNamedField>( |
5509 heap_number, HObjectAccess::ForHeapNumberValue()); | 5496 heap_number, HObjectAccess::ForHeapNumberValue()); |
5510 } | 5497 } |
5511 return New<HLoadNamedField>(object, access); | 5498 return New<HLoadNamedField>(object, access); |
5512 } | 5499 } |
5513 | 5500 |
5514 | 5501 |
| 5502 HInstruction* HGraphBuilder::AddLoadNamedField(HValue* object, |
| 5503 HObjectAccess access) { |
| 5504 return AddInstruction(BuildLoadNamedField(object, access)); |
| 5505 } |
| 5506 |
| 5507 |
5515 HInstruction* HGraphBuilder::BuildLoadStringLength(HValue* object, | 5508 HInstruction* HGraphBuilder::BuildLoadStringLength(HValue* object, |
5516 HValue* checked_string) { | 5509 HValue* checked_string) { |
5517 if (FLAG_fold_constants && object->IsConstant()) { | 5510 if (FLAG_fold_constants && object->IsConstant()) { |
5518 HConstant* constant = HConstant::cast(object); | 5511 HConstant* constant = HConstant::cast(object); |
5519 if (constant->HasStringValue()) { | 5512 if (constant->HasStringValue()) { |
5520 return New<HConstant>(constant->StringValue()->length()); | 5513 return New<HConstant>(constant->StringValue()->length()); |
5521 } | 5514 } |
5522 } | 5515 } |
5523 return BuildLoadNamedField(checked_string, HObjectAccess::ForStringLength()); | 5516 return BuildLoadNamedField(checked_string, HObjectAccess::ForStringLength()); |
5524 } | 5517 } |
5525 | 5518 |
5526 | 5519 |
5527 HInstruction* HOptimizedGraphBuilder::BuildLoadNamedGeneric( | 5520 HInstruction* HOptimizedGraphBuilder::BuildLoadNamedGeneric( |
5528 HValue* object, | 5521 HValue* object, |
5529 Handle<String> name, | 5522 Handle<String> name, |
5530 Property* expr) { | 5523 Property* expr) { |
5531 if (expr->IsUninitialized()) { | 5524 if (expr->IsUninitialized()) { |
5532 Add<HDeoptimize>("Insufficient type feedback for generic named load", | 5525 Add<HDeoptimize>("Insufficient type feedback for generic named load", |
5533 Deoptimizer::SOFT); | 5526 Deoptimizer::SOFT); |
5534 } | 5527 } |
5535 HValue* context = environment()->context(); | 5528 return New<HLoadNamedGeneric>(object, name); |
5536 return new(zone()) HLoadNamedGeneric(context, object, name); | |
5537 } | 5529 } |
5538 | 5530 |
5539 | 5531 |
5540 | 5532 |
5541 HInstruction* HOptimizedGraphBuilder::BuildLoadKeyedGeneric(HValue* object, | 5533 HInstruction* HOptimizedGraphBuilder::BuildLoadKeyedGeneric(HValue* object, |
5542 HValue* key) { | 5534 HValue* key) { |
5543 HValue* context = environment()->context(); | 5535 return New<HLoadKeyedGeneric>(object, key); |
5544 return new(zone()) HLoadKeyedGeneric(context, object, key); | |
5545 } | 5536 } |
5546 | 5537 |
5547 | 5538 |
5548 LoadKeyedHoleMode HOptimizedGraphBuilder::BuildKeyedHoleMode(Handle<Map> map) { | 5539 LoadKeyedHoleMode HOptimizedGraphBuilder::BuildKeyedHoleMode(Handle<Map> map) { |
5549 // Loads from a "stock" fast holey double arrays can elide the hole check. | 5540 // Loads from a "stock" fast holey double arrays can elide the hole check. |
5550 LoadKeyedHoleMode load_mode = NEVER_RETURN_HOLE; | 5541 LoadKeyedHoleMode load_mode = NEVER_RETURN_HOLE; |
5551 if (*map == isolate()->get_initial_js_array_map(FAST_HOLEY_DOUBLE_ELEMENTS) && | 5542 if (*map == isolate()->get_initial_js_array_map(FAST_HOLEY_DOUBLE_ELEMENTS) && |
5552 isolate()->IsFastArrayConstructorPrototypeChainIntact()) { | 5543 isolate()->IsFastArrayConstructorPrototypeChainIntact()) { |
5553 Handle<JSObject> prototype(JSObject::cast(map->prototype()), isolate()); | 5544 Handle<JSObject> prototype(JSObject::cast(map->prototype()), isolate()); |
5554 Handle<JSObject> object_prototype = isolate()->initial_object_prototype(); | 5545 Handle<JSObject> object_prototype = isolate()->initial_object_prototype(); |
(...skipping 266 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5821 } | 5812 } |
5822 *has_side_effects = instr->HasObservableSideEffects(); | 5813 *has_side_effects = instr->HasObservableSideEffects(); |
5823 return instr; | 5814 return instr; |
5824 } | 5815 } |
5825 | 5816 |
5826 | 5817 |
5827 HInstruction* HOptimizedGraphBuilder::BuildStoreKeyedGeneric( | 5818 HInstruction* HOptimizedGraphBuilder::BuildStoreKeyedGeneric( |
5828 HValue* object, | 5819 HValue* object, |
5829 HValue* key, | 5820 HValue* key, |
5830 HValue* value) { | 5821 HValue* value) { |
5831 HValue* context = environment()->context(); | 5822 return New<HStoreKeyedGeneric>( |
5832 return new(zone()) HStoreKeyedGeneric( | |
5833 context, | |
5834 object, | 5823 object, |
5835 key, | 5824 key, |
5836 value, | 5825 value, |
5837 function_strict_mode_flag()); | 5826 function_strict_mode_flag()); |
5838 } | 5827 } |
5839 | 5828 |
5840 | 5829 |
5841 void HOptimizedGraphBuilder::EnsureArgumentsArePushedForAccess() { | 5830 void HOptimizedGraphBuilder::EnsureArgumentsArePushedForAccess() { |
5842 // Outermost function already has arguments on the stack. | 5831 // Outermost function already has arguments on the stack. |
5843 if (function_state()->outer() == NULL) return; | 5832 if (function_state()->outer() == NULL) return; |
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5890 } | 5879 } |
5891 } else { | 5880 } else { |
5892 Push(graph()->GetArgumentsObject()); | 5881 Push(graph()->GetArgumentsObject()); |
5893 CHECK_ALIVE_OR_RETURN(VisitForValue(expr->key()), true); | 5882 CHECK_ALIVE_OR_RETURN(VisitForValue(expr->key()), true); |
5894 HValue* key = Pop(); | 5883 HValue* key = Pop(); |
5895 Drop(1); // Arguments object. | 5884 Drop(1); // Arguments object. |
5896 if (function_state()->outer() == NULL) { | 5885 if (function_state()->outer() == NULL) { |
5897 HInstruction* elements = Add<HArgumentsElements>(false); | 5886 HInstruction* elements = Add<HArgumentsElements>(false); |
5898 HInstruction* length = Add<HArgumentsLength>(elements); | 5887 HInstruction* length = Add<HArgumentsLength>(elements); |
5899 HInstruction* checked_key = Add<HBoundsCheck>(key, length); | 5888 HInstruction* checked_key = Add<HBoundsCheck>(key, length); |
5900 result = new(zone()) HAccessArgumentsAt(elements, length, checked_key); | 5889 result = New<HAccessArgumentsAt>(elements, length, checked_key); |
5901 } else { | 5890 } else { |
5902 EnsureArgumentsArePushedForAccess(); | 5891 EnsureArgumentsArePushedForAccess(); |
5903 | 5892 |
5904 // Number of arguments without receiver. | 5893 // Number of arguments without receiver. |
5905 HInstruction* elements = function_state()->arguments_elements(); | 5894 HInstruction* elements = function_state()->arguments_elements(); |
5906 int argument_count = environment()-> | 5895 int argument_count = environment()-> |
5907 arguments_environment()->parameter_count() - 1; | 5896 arguments_environment()->parameter_count() - 1; |
5908 HInstruction* length = Add<HConstant>(argument_count); | 5897 HInstruction* length = Add<HConstant>(argument_count); |
5909 HInstruction* checked_key = Add<HBoundsCheck>(key, length); | 5898 HInstruction* checked_key = Add<HBoundsCheck>(key, length); |
5910 result = new(zone()) HAccessArgumentsAt(elements, length, checked_key); | 5899 result = New<HAccessArgumentsAt>(elements, length, checked_key); |
5911 } | 5900 } |
5912 } | 5901 } |
5913 ast_context()->ReturnInstruction(result, expr->id()); | 5902 ast_context()->ReturnInstruction(result, expr->id()); |
5914 return true; | 5903 return true; |
5915 } | 5904 } |
5916 | 5905 |
5917 | 5906 |
5918 void HOptimizedGraphBuilder::PushLoad(Property* expr, | 5907 void HOptimizedGraphBuilder::PushLoad(Property* expr, |
5919 HValue* object, | 5908 HValue* object, |
5920 HValue* key) { | 5909 HValue* key) { |
(...skipping 11 matching lines...) Expand all Loading... |
5932 return true; | 5921 return true; |
5933 } | 5922 } |
5934 | 5923 |
5935 | 5924 |
5936 void HOptimizedGraphBuilder::BuildLoad(Property* expr, | 5925 void HOptimizedGraphBuilder::BuildLoad(Property* expr, |
5937 BailoutId ast_id) { | 5926 BailoutId ast_id) { |
5938 HInstruction* instr = NULL; | 5927 HInstruction* instr = NULL; |
5939 if (expr->IsStringAccess()) { | 5928 if (expr->IsStringAccess()) { |
5940 HValue* index = Pop(); | 5929 HValue* index = Pop(); |
5941 HValue* string = Pop(); | 5930 HValue* string = Pop(); |
5942 HValue* context = environment()->context(); | 5931 HInstruction* char_code = BuildStringCharCodeAt(string, index); |
5943 HInstruction* char_code = | |
5944 BuildStringCharCodeAt(string, index); | |
5945 AddInstruction(char_code); | 5932 AddInstruction(char_code); |
5946 instr = HStringCharFromCode::New(zone(), context, char_code); | 5933 instr = NewUncasted<HStringCharFromCode>(char_code); |
5947 | 5934 |
5948 } else if (expr->IsFunctionPrototype()) { | 5935 } else if (expr->IsFunctionPrototype()) { |
5949 HValue* function = Pop(); | 5936 HValue* function = Pop(); |
5950 BuildCheckHeapObject(function); | 5937 BuildCheckHeapObject(function); |
5951 instr = new(zone()) HLoadFunctionPrototype(function); | 5938 instr = New<HLoadFunctionPrototype>(function); |
5952 | 5939 |
5953 } else if (expr->key()->IsPropertyName()) { | 5940 } else if (expr->key()->IsPropertyName()) { |
5954 Handle<String> name = expr->key()->AsLiteral()->AsPropertyName(); | 5941 Handle<String> name = expr->key()->AsLiteral()->AsPropertyName(); |
5955 HValue* object = Pop(); | 5942 HValue* object = Pop(); |
5956 | 5943 |
5957 SmallMapList* types; | 5944 SmallMapList* types; |
5958 ComputeReceiverTypes(expr, object, &types); | 5945 ComputeReceiverTypes(expr, object, &types); |
5959 ASSERT(types != NULL); | 5946 ASSERT(types != NULL); |
5960 | 5947 |
5961 if (types->length() > 0) { | 5948 if (types->length() > 0) { |
(...skipping 765 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
6727 case kMathRound: | 6714 case kMathRound: |
6728 case kMathFloor: | 6715 case kMathFloor: |
6729 case kMathAbs: | 6716 case kMathAbs: |
6730 case kMathSqrt: | 6717 case kMathSqrt: |
6731 case kMathLog: | 6718 case kMathLog: |
6732 case kMathSin: | 6719 case kMathSin: |
6733 case kMathCos: | 6720 case kMathCos: |
6734 case kMathTan: | 6721 case kMathTan: |
6735 if (expr->arguments()->length() == 1) { | 6722 if (expr->arguments()->length() == 1) { |
6736 HValue* argument = Pop(); | 6723 HValue* argument = Pop(); |
6737 HValue* context = environment()->context(); | |
6738 Drop(1); // Receiver. | 6724 Drop(1); // Receiver. |
6739 HInstruction* op = | 6725 HInstruction* op = NewUncasted<HUnaryMathOperation>(argument, id); |
6740 HUnaryMathOperation::New(zone(), context, argument, id); | |
6741 if (drop_extra) Drop(1); // Optionally drop the function. | 6726 if (drop_extra) Drop(1); // Optionally drop the function. |
6742 ast_context()->ReturnInstruction(op, expr->id()); | 6727 ast_context()->ReturnInstruction(op, expr->id()); |
6743 return true; | 6728 return true; |
6744 } | 6729 } |
6745 break; | 6730 break; |
6746 case kMathImul: | 6731 case kMathImul: |
6747 if (expr->arguments()->length() == 2) { | 6732 if (expr->arguments()->length() == 2) { |
6748 HValue* right = Pop(); | 6733 HValue* right = Pop(); |
6749 HValue* left = Pop(); | 6734 HValue* left = Pop(); |
6750 Drop(1); // Receiver. | 6735 Drop(1); // Receiver. |
6751 HValue* context = environment()->context(); | 6736 HInstruction* op = HMul::NewImul(zone(), context(), left, right); |
6752 HInstruction* op = HMul::NewImul(zone(), context, left, right); | |
6753 if (drop_extra) Drop(1); // Optionally drop the function. | 6737 if (drop_extra) Drop(1); // Optionally drop the function. |
6754 ast_context()->ReturnInstruction(op, expr->id()); | 6738 ast_context()->ReturnInstruction(op, expr->id()); |
6755 return true; | 6739 return true; |
6756 } | 6740 } |
6757 break; | 6741 break; |
6758 default: | 6742 default: |
6759 // Not supported for inlining yet. | 6743 // Not supported for inlining yet. |
6760 break; | 6744 break; |
6761 } | 6745 } |
6762 return false; | 6746 return false; |
6763 } | 6747 } |
6764 | 6748 |
6765 | 6749 |
6766 bool HOptimizedGraphBuilder::TryInlineBuiltinMethodCall( | 6750 bool HOptimizedGraphBuilder::TryInlineBuiltinMethodCall( |
6767 Call* expr, | 6751 Call* expr, |
6768 HValue* receiver, | 6752 HValue* receiver, |
6769 Handle<Map> receiver_map, | 6753 Handle<Map> receiver_map, |
6770 CheckType check_type) { | 6754 CheckType check_type) { |
6771 ASSERT(check_type != RECEIVER_MAP_CHECK || !receiver_map.is_null()); | 6755 ASSERT(check_type != RECEIVER_MAP_CHECK || !receiver_map.is_null()); |
6772 // Try to inline calls like Math.* as operations in the calling function. | 6756 // Try to inline calls like Math.* as operations in the calling function. |
6773 if (!expr->target()->shared()->HasBuiltinFunctionId()) return false; | 6757 if (!expr->target()->shared()->HasBuiltinFunctionId()) return false; |
6774 BuiltinFunctionId id = expr->target()->shared()->builtin_function_id(); | 6758 BuiltinFunctionId id = expr->target()->shared()->builtin_function_id(); |
6775 int argument_count = expr->arguments()->length() + 1; // Plus receiver. | 6759 int argument_count = expr->arguments()->length() + 1; // Plus receiver. |
6776 switch (id) { | 6760 switch (id) { |
6777 case kStringCharCodeAt: | 6761 case kStringCharCodeAt: |
6778 case kStringCharAt: | 6762 case kStringCharAt: |
6779 if (argument_count == 2 && check_type == STRING_CHECK) { | 6763 if (argument_count == 2 && check_type == STRING_CHECK) { |
6780 HValue* index = Pop(); | 6764 HValue* index = Pop(); |
6781 HValue* string = Pop(); | 6765 HValue* string = Pop(); |
6782 HValue* context = environment()->context(); | |
6783 ASSERT(!expr->holder().is_null()); | 6766 ASSERT(!expr->holder().is_null()); |
6784 BuildCheckPrototypeMaps(Call::GetPrototypeForPrimitiveCheck( | 6767 BuildCheckPrototypeMaps(Call::GetPrototypeForPrimitiveCheck( |
6785 STRING_CHECK, expr->holder()->GetIsolate()), | 6768 STRING_CHECK, expr->holder()->GetIsolate()), |
6786 expr->holder()); | 6769 expr->holder()); |
6787 HInstruction* char_code = | 6770 HInstruction* char_code = |
6788 BuildStringCharCodeAt(string, index); | 6771 BuildStringCharCodeAt(string, index); |
6789 if (id == kStringCharCodeAt) { | 6772 if (id == kStringCharCodeAt) { |
6790 ast_context()->ReturnInstruction(char_code, expr->id()); | 6773 ast_context()->ReturnInstruction(char_code, expr->id()); |
6791 return true; | 6774 return true; |
6792 } | 6775 } |
6793 AddInstruction(char_code); | 6776 AddInstruction(char_code); |
6794 HInstruction* result = | 6777 HInstruction* result = NewUncasted<HStringCharFromCode>(char_code); |
6795 HStringCharFromCode::New(zone(), context, char_code); | |
6796 ast_context()->ReturnInstruction(result, expr->id()); | 6778 ast_context()->ReturnInstruction(result, expr->id()); |
6797 return true; | 6779 return true; |
6798 } | 6780 } |
6799 break; | 6781 break; |
6800 case kStringFromCharCode: | 6782 case kStringFromCharCode: |
6801 if (argument_count == 2 && check_type == RECEIVER_MAP_CHECK) { | 6783 if (argument_count == 2 && check_type == RECEIVER_MAP_CHECK) { |
6802 AddCheckConstantFunction(expr->holder(), receiver, receiver_map); | 6784 AddCheckConstantFunction(expr->holder(), receiver, receiver_map); |
6803 HValue* argument = Pop(); | 6785 HValue* argument = Pop(); |
6804 HValue* context = environment()->context(); | |
6805 Drop(1); // Receiver. | 6786 Drop(1); // Receiver. |
6806 HInstruction* result = | 6787 HInstruction* result = NewUncasted<HStringCharFromCode>(argument); |
6807 HStringCharFromCode::New(zone(), context, argument); | |
6808 ast_context()->ReturnInstruction(result, expr->id()); | 6788 ast_context()->ReturnInstruction(result, expr->id()); |
6809 return true; | 6789 return true; |
6810 } | 6790 } |
6811 break; | 6791 break; |
6812 case kMathExp: | 6792 case kMathExp: |
6813 if (!FLAG_fast_math) break; | 6793 if (!FLAG_fast_math) break; |
6814 // Fall through if FLAG_fast_math. | 6794 // Fall through if FLAG_fast_math. |
6815 case kMathRound: | 6795 case kMathRound: |
6816 case kMathFloor: | 6796 case kMathFloor: |
6817 case kMathAbs: | 6797 case kMathAbs: |
6818 case kMathSqrt: | 6798 case kMathSqrt: |
6819 case kMathLog: | 6799 case kMathLog: |
6820 case kMathSin: | 6800 case kMathSin: |
6821 case kMathCos: | 6801 case kMathCos: |
6822 case kMathTan: | 6802 case kMathTan: |
6823 if (argument_count == 2 && check_type == RECEIVER_MAP_CHECK) { | 6803 if (argument_count == 2 && check_type == RECEIVER_MAP_CHECK) { |
6824 AddCheckConstantFunction(expr->holder(), receiver, receiver_map); | 6804 AddCheckConstantFunction(expr->holder(), receiver, receiver_map); |
6825 HValue* argument = Pop(); | 6805 HValue* argument = Pop(); |
6826 HValue* context = environment()->context(); | |
6827 Drop(1); // Receiver. | 6806 Drop(1); // Receiver. |
6828 HInstruction* op = | 6807 HInstruction* op = NewUncasted<HUnaryMathOperation>(argument, id); |
6829 HUnaryMathOperation::New(zone(), context, argument, id); | |
6830 ast_context()->ReturnInstruction(op, expr->id()); | 6808 ast_context()->ReturnInstruction(op, expr->id()); |
6831 return true; | 6809 return true; |
6832 } | 6810 } |
6833 break; | 6811 break; |
6834 case kMathPow: | 6812 case kMathPow: |
6835 if (argument_count == 3 && check_type == RECEIVER_MAP_CHECK) { | 6813 if (argument_count == 3 && check_type == RECEIVER_MAP_CHECK) { |
6836 AddCheckConstantFunction(expr->holder(), receiver, receiver_map); | 6814 AddCheckConstantFunction(expr->holder(), receiver, receiver_map); |
6837 HValue* right = Pop(); | 6815 HValue* right = Pop(); |
6838 HValue* left = Pop(); | 6816 HValue* left = Pop(); |
6839 Pop(); // Pop receiver. | 6817 Pop(); // Pop receiver. |
6840 HValue* context = environment()->context(); | |
6841 HInstruction* result = NULL; | 6818 HInstruction* result = NULL; |
6842 // Use sqrt() if exponent is 0.5 or -0.5. | 6819 // Use sqrt() if exponent is 0.5 or -0.5. |
6843 if (right->IsConstant() && HConstant::cast(right)->HasDoubleValue()) { | 6820 if (right->IsConstant() && HConstant::cast(right)->HasDoubleValue()) { |
6844 double exponent = HConstant::cast(right)->DoubleValue(); | 6821 double exponent = HConstant::cast(right)->DoubleValue(); |
6845 if (exponent == 0.5) { | 6822 if (exponent == 0.5) { |
6846 result = | 6823 result = NewUncasted<HUnaryMathOperation>(left, kMathPowHalf); |
6847 HUnaryMathOperation::New(zone(), context, left, kMathPowHalf); | |
6848 } else if (exponent == -0.5) { | 6824 } else if (exponent == -0.5) { |
6849 HValue* one = graph()->GetConstant1(); | 6825 HValue* one = graph()->GetConstant1(); |
6850 HInstruction* sqrt = | 6826 HInstruction* sqrt = AddUncasted<HUnaryMathOperation>( |
6851 HUnaryMathOperation::New(zone(), context, left, kMathPowHalf); | 6827 left, kMathPowHalf); |
6852 AddInstruction(sqrt); | |
6853 // MathPowHalf doesn't have side effects so there's no need for | 6828 // MathPowHalf doesn't have side effects so there's no need for |
6854 // an environment simulation here. | 6829 // an environment simulation here. |
6855 ASSERT(!sqrt->HasObservableSideEffects()); | 6830 ASSERT(!sqrt->HasObservableSideEffects()); |
6856 result = HDiv::New(zone(), context, one, sqrt); | 6831 result = NewUncasted<HDiv>(one, sqrt); |
6857 } else if (exponent == 2.0) { | 6832 } else if (exponent == 2.0) { |
6858 result = HMul::New(zone(), context, left, left); | 6833 result = NewUncasted<HMul>(left, left); |
6859 } | 6834 } |
6860 } | 6835 } |
6861 | 6836 |
6862 if (result == NULL) { | 6837 if (result == NULL) { |
6863 result = HPower::New(zone(), context, left, right); | 6838 result = NewUncasted<HPower>(left, right); |
6864 } | 6839 } |
6865 ast_context()->ReturnInstruction(result, expr->id()); | 6840 ast_context()->ReturnInstruction(result, expr->id()); |
6866 return true; | 6841 return true; |
6867 } | 6842 } |
6868 break; | 6843 break; |
6869 case kMathRandom: | 6844 case kMathRandom: |
6870 if (argument_count == 1 && check_type == RECEIVER_MAP_CHECK) { | 6845 if (argument_count == 1 && check_type == RECEIVER_MAP_CHECK) { |
6871 AddCheckConstantFunction(expr->holder(), receiver, receiver_map); | 6846 AddCheckConstantFunction(expr->holder(), receiver, receiver_map); |
6872 Drop(1); // Receiver. | 6847 Drop(1); // Receiver. |
6873 HGlobalObject* global_object = Add<HGlobalObject>(); | 6848 HGlobalObject* global_object = Add<HGlobalObject>(); |
6874 HRandom* result = new(zone()) HRandom(global_object); | 6849 HRandom* result = New<HRandom>(global_object); |
6875 ast_context()->ReturnInstruction(result, expr->id()); | 6850 ast_context()->ReturnInstruction(result, expr->id()); |
6876 return true; | 6851 return true; |
6877 } | 6852 } |
6878 break; | 6853 break; |
6879 case kMathMax: | 6854 case kMathMax: |
6880 case kMathMin: | 6855 case kMathMin: |
6881 if (argument_count == 3 && check_type == RECEIVER_MAP_CHECK) { | 6856 if (argument_count == 3 && check_type == RECEIVER_MAP_CHECK) { |
6882 AddCheckConstantFunction(expr->holder(), receiver, receiver_map); | 6857 AddCheckConstantFunction(expr->holder(), receiver, receiver_map); |
6883 HValue* right = Pop(); | 6858 HValue* right = Pop(); |
6884 HValue* left = Pop(); | 6859 HValue* left = Pop(); |
6885 Drop(1); // Receiver. | 6860 Drop(1); // Receiver. |
6886 HValue* context = environment()->context(); | |
6887 HMathMinMax::Operation op = (id == kMathMin) ? HMathMinMax::kMathMin | 6861 HMathMinMax::Operation op = (id == kMathMin) ? HMathMinMax::kMathMin |
6888 : HMathMinMax::kMathMax; | 6862 : HMathMinMax::kMathMax; |
6889 HInstruction* result = | 6863 HInstruction* result = NewUncasted<HMathMinMax>(left, right, op); |
6890 HMathMinMax::New(zone(), context, left, right, op); | |
6891 ast_context()->ReturnInstruction(result, expr->id()); | 6864 ast_context()->ReturnInstruction(result, expr->id()); |
6892 return true; | 6865 return true; |
6893 } | 6866 } |
6894 break; | 6867 break; |
6895 case kMathImul: | 6868 case kMathImul: |
6896 if (argument_count == 3 && check_type == RECEIVER_MAP_CHECK) { | 6869 if (argument_count == 3 && check_type == RECEIVER_MAP_CHECK) { |
6897 AddCheckConstantFunction(expr->holder(), receiver, receiver_map); | 6870 AddCheckConstantFunction(expr->holder(), receiver, receiver_map); |
6898 HValue* right = Pop(); | 6871 HValue* right = Pop(); |
6899 HValue* left = Pop(); | 6872 HValue* left = Pop(); |
6900 Drop(1); // Receiver. | 6873 Drop(1); // Receiver. |
6901 HValue* context = environment()->context(); | 6874 HInstruction* result = HMul::NewImul(zone(), context(), left, right); |
6902 HInstruction* result = HMul::NewImul(zone(), context, left, right); | |
6903 ast_context()->ReturnInstruction(result, expr->id()); | 6875 ast_context()->ReturnInstruction(result, expr->id()); |
6904 return true; | 6876 return true; |
6905 } | 6877 } |
6906 break; | 6878 break; |
6907 default: | 6879 default: |
6908 // Not yet supported for inlining. | 6880 // Not yet supported for inlining. |
6909 break; | 6881 break; |
6910 } | 6882 } |
6911 return false; | 6883 return false; |
6912 } | 6884 } |
(...skipping 30 matching lines...) Expand all Loading... |
6943 AddCheckConstantFunction(expr->holder(), function, function_map); | 6915 AddCheckConstantFunction(expr->holder(), function, function_map); |
6944 Drop(1); | 6916 Drop(1); |
6945 | 6917 |
6946 CHECK_ALIVE_OR_RETURN(VisitForValue(args->at(0)), true); | 6918 CHECK_ALIVE_OR_RETURN(VisitForValue(args->at(0)), true); |
6947 HValue* receiver = Pop(); | 6919 HValue* receiver = Pop(); |
6948 | 6920 |
6949 if (function_state()->outer() == NULL) { | 6921 if (function_state()->outer() == NULL) { |
6950 HInstruction* elements = Add<HArgumentsElements>(false); | 6922 HInstruction* elements = Add<HArgumentsElements>(false); |
6951 HInstruction* length = Add<HArgumentsLength>(elements); | 6923 HInstruction* length = Add<HArgumentsLength>(elements); |
6952 HValue* wrapped_receiver = BuildWrapReceiver(receiver, function); | 6924 HValue* wrapped_receiver = BuildWrapReceiver(receiver, function); |
6953 HInstruction* result = | 6925 HInstruction* result = New<HApplyArguments>(function, |
6954 new(zone()) HApplyArguments(function, | 6926 wrapped_receiver, |
6955 wrapped_receiver, | 6927 length, |
6956 length, | 6928 elements); |
6957 elements); | |
6958 ast_context()->ReturnInstruction(result, expr->id()); | 6929 ast_context()->ReturnInstruction(result, expr->id()); |
6959 return true; | 6930 return true; |
6960 } else { | 6931 } else { |
6961 // We are inside inlined function and we know exactly what is inside | 6932 // We are inside inlined function and we know exactly what is inside |
6962 // arguments object. But we need to be able to materialize at deopt. | 6933 // arguments object. But we need to be able to materialize at deopt. |
6963 ASSERT_EQ(environment()->arguments_environment()->parameter_count(), | 6934 ASSERT_EQ(environment()->arguments_environment()->parameter_count(), |
6964 function_state()->entry()->arguments_object()->arguments_count()); | 6935 function_state()->entry()->arguments_object()->arguments_count()); |
6965 HArgumentsObject* args = function_state()->entry()->arguments_object(); | 6936 HArgumentsObject* args = function_state()->entry()->arguments_object(); |
6966 const ZoneList<HValue*>* arguments_values = args->arguments_values(); | 6937 const ZoneList<HValue*>* arguments_values = args->arguments_values(); |
6967 int arguments_count = arguments_values->length(); | 6938 int arguments_count = arguments_values->length(); |
(...skipping 10 matching lines...) Expand all Loading... |
6978 int args_count = arguments_count - 1; // Excluding receiver. | 6949 int args_count = arguments_count - 1; // Excluding receiver. |
6979 if (TryInlineApply(known_function, expr, args_count)) return true; | 6950 if (TryInlineApply(known_function, expr, args_count)) return true; |
6980 } | 6951 } |
6981 | 6952 |
6982 Drop(arguments_count - 1); | 6953 Drop(arguments_count - 1); |
6983 PushAndAdd(New<HPushArgument>(Pop())); | 6954 PushAndAdd(New<HPushArgument>(Pop())); |
6984 for (int i = 1; i < arguments_count; i++) { | 6955 for (int i = 1; i < arguments_count; i++) { |
6985 PushAndAdd(New<HPushArgument>(arguments_values->at(i))); | 6956 PushAndAdd(New<HPushArgument>(arguments_values->at(i))); |
6986 } | 6957 } |
6987 | 6958 |
6988 HValue* context = environment()->context(); | 6959 HInvokeFunction* call = New<HInvokeFunction>(function, |
6989 HInvokeFunction* call = new(zone()) HInvokeFunction( | 6960 known_function, |
6990 context, | 6961 arguments_count); |
6991 function, | |
6992 known_function, | |
6993 arguments_count); | |
6994 Drop(arguments_count); | 6962 Drop(arguments_count); |
6995 ast_context()->ReturnInstruction(call, expr->id()); | 6963 ast_context()->ReturnInstruction(call, expr->id()); |
6996 return true; | 6964 return true; |
6997 } | 6965 } |
6998 } | 6966 } |
6999 | 6967 |
7000 | 6968 |
7001 void HOptimizedGraphBuilder::VisitCall(Call* expr) { | 6969 void HOptimizedGraphBuilder::VisitCall(Call* expr) { |
7002 ASSERT(!HasStackOverflow()); | 6970 ASSERT(!HasStackOverflow()); |
7003 ASSERT(current_block() != NULL); | 6971 ASSERT(current_block() != NULL); |
(...skipping 87 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
7091 LookupResult lookup(isolate()); | 7059 LookupResult lookup(isolate()); |
7092 GlobalPropertyAccess type = LookupGlobalProperty(var, &lookup, false); | 7060 GlobalPropertyAccess type = LookupGlobalProperty(var, &lookup, false); |
7093 if (type == kUseCell && | 7061 if (type == kUseCell && |
7094 !current_info()->global_object()->IsAccessCheckNeeded()) { | 7062 !current_info()->global_object()->IsAccessCheckNeeded()) { |
7095 Handle<GlobalObject> global(current_info()->global_object()); | 7063 Handle<GlobalObject> global(current_info()->global_object()); |
7096 known_global_function = expr->ComputeGlobalTarget(global, &lookup); | 7064 known_global_function = expr->ComputeGlobalTarget(global, &lookup); |
7097 } | 7065 } |
7098 if (known_global_function) { | 7066 if (known_global_function) { |
7099 // Push the global object instead of the global receiver because | 7067 // Push the global object instead of the global receiver because |
7100 // code generated by the full code generator expects it. | 7068 // code generated by the full code generator expects it. |
7101 HValue* context = environment()->context(); | 7069 HGlobalObject* global_object = New<HGlobalObject>(); |
7102 HGlobalObject* global_object = new(zone()) HGlobalObject(context); | |
7103 PushAndAdd(global_object); | 7070 PushAndAdd(global_object); |
7104 CHECK_ALIVE(VisitExpressions(expr->arguments())); | 7071 CHECK_ALIVE(VisitExpressions(expr->arguments())); |
7105 | 7072 |
7106 CHECK_ALIVE(VisitForValue(expr->expression())); | 7073 CHECK_ALIVE(VisitForValue(expr->expression())); |
7107 HValue* function = Pop(); | 7074 HValue* function = Pop(); |
7108 Add<HCheckValue>(function, expr->target()); | 7075 Add<HCheckValue>(function, expr->target()); |
7109 | 7076 |
7110 // Replace the global object with the global receiver. | 7077 // Replace the global object with the global receiver. |
7111 HGlobalReceiver* global_receiver = Add<HGlobalReceiver>(global_object); | 7078 HGlobalReceiver* global_receiver = Add<HGlobalReceiver>(global_object); |
7112 // Index of the receiver from the top of the expression stack. | 7079 // Index of the receiver from the top of the expression stack. |
(...skipping 14 matching lines...) Expand all Loading... |
7127 | 7094 |
7128 if (expr->target().is_identical_to(current_info()->closure())) { | 7095 if (expr->target().is_identical_to(current_info()->closure())) { |
7129 graph()->MarkRecursive(); | 7096 graph()->MarkRecursive(); |
7130 } | 7097 } |
7131 | 7098 |
7132 if (CallStubCompiler::HasCustomCallGenerator(expr->target())) { | 7099 if (CallStubCompiler::HasCustomCallGenerator(expr->target())) { |
7133 // When the target has a custom call IC generator, use the IC, | 7100 // When the target has a custom call IC generator, use the IC, |
7134 // because it is likely to generate better code. | 7101 // because it is likely to generate better code. |
7135 call = PreProcessCall(New<HCallNamed>(var->name(), argument_count)); | 7102 call = PreProcessCall(New<HCallNamed>(var->name(), argument_count)); |
7136 } else { | 7103 } else { |
7137 call = PreProcessCall(new(zone()) HCallKnownGlobal(expr->target(), | 7104 call = PreProcessCall(New<HCallKnownGlobal>( |
7138 argument_count)); | 7105 expr->target(), argument_count)); |
7139 } | 7106 } |
7140 } else { | 7107 } else { |
7141 HGlobalObject* receiver = Add<HGlobalObject>(); | 7108 HGlobalObject* receiver = Add<HGlobalObject>(); |
7142 PushAndAdd(New<HPushArgument>(receiver)); | 7109 PushAndAdd(New<HPushArgument>(receiver)); |
7143 CHECK_ALIVE(VisitArgumentList(expr->arguments())); | 7110 CHECK_ALIVE(VisitArgumentList(expr->arguments())); |
7144 | 7111 |
7145 call = New<HCallGlobal>(var->name(), argument_count); | 7112 call = New<HCallGlobal>(var->name(), argument_count); |
7146 Drop(argument_count); | 7113 Drop(argument_count); |
7147 } | 7114 } |
7148 | 7115 |
(...skipping 977 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
8126 return ast_context()->ReturnInstruction(instr, expr->id()); | 8093 return ast_context()->ReturnInstruction(instr, expr->id()); |
8127 } | 8094 } |
8128 | 8095 |
8129 | 8096 |
8130 void HOptimizedGraphBuilder::HandleLiteralCompareTypeof(CompareOperation* expr, | 8097 void HOptimizedGraphBuilder::HandleLiteralCompareTypeof(CompareOperation* expr, |
8131 Expression* sub_expr, | 8098 Expression* sub_expr, |
8132 Handle<String> check) { | 8099 Handle<String> check) { |
8133 CHECK_ALIVE(VisitForTypeOf(sub_expr)); | 8100 CHECK_ALIVE(VisitForTypeOf(sub_expr)); |
8134 if (!FLAG_emit_opt_code_positions) SetSourcePosition(expr->position()); | 8101 if (!FLAG_emit_opt_code_positions) SetSourcePosition(expr->position()); |
8135 HValue* value = Pop(); | 8102 HValue* value = Pop(); |
8136 HTypeofIsAndBranch* instr = new(zone()) HTypeofIsAndBranch(value, check); | 8103 HTypeofIsAndBranch* instr = New<HTypeofIsAndBranch>(value, check); |
8137 return ast_context()->ReturnControl(instr, expr->id()); | 8104 return ast_context()->ReturnControl(instr, expr->id()); |
8138 } | 8105 } |
8139 | 8106 |
8140 | 8107 |
8141 static bool IsLiteralCompareBool(Isolate* isolate, | 8108 static bool IsLiteralCompareBool(Isolate* isolate, |
8142 HValue* left, | 8109 HValue* left, |
8143 Token::Value op, | 8110 Token::Value op, |
8144 HValue* right) { | 8111 HValue* right) { |
8145 return op == Token::EQ_STRICT && | 8112 return op == Token::EQ_STRICT && |
8146 ((left->IsConstant() && | 8113 ((left->IsConstant() && |
(...skipping 25 matching lines...) Expand all Loading... |
8172 return HandleLiteralCompareNil(expr, sub_expr, kNullValue); | 8139 return HandleLiteralCompareNil(expr, sub_expr, kNullValue); |
8173 } | 8140 } |
8174 | 8141 |
8175 if (IsClassOfTest(expr)) { | 8142 if (IsClassOfTest(expr)) { |
8176 CallRuntime* call = expr->left()->AsCallRuntime(); | 8143 CallRuntime* call = expr->left()->AsCallRuntime(); |
8177 ASSERT(call->arguments()->length() == 1); | 8144 ASSERT(call->arguments()->length() == 1); |
8178 CHECK_ALIVE(VisitForValue(call->arguments()->at(0))); | 8145 CHECK_ALIVE(VisitForValue(call->arguments()->at(0))); |
8179 HValue* value = Pop(); | 8146 HValue* value = Pop(); |
8180 Literal* literal = expr->right()->AsLiteral(); | 8147 Literal* literal = expr->right()->AsLiteral(); |
8181 Handle<String> rhs = Handle<String>::cast(literal->value()); | 8148 Handle<String> rhs = Handle<String>::cast(literal->value()); |
8182 HClassOfTestAndBranch* instr = | 8149 HClassOfTestAndBranch* instr = New<HClassOfTestAndBranch>(value, rhs); |
8183 new(zone()) HClassOfTestAndBranch(value, rhs); | |
8184 return ast_context()->ReturnControl(instr, expr->id()); | 8150 return ast_context()->ReturnControl(instr, expr->id()); |
8185 } | 8151 } |
8186 | 8152 |
8187 Handle<Type> left_type = expr->left()->bounds().lower; | 8153 Handle<Type> left_type = expr->left()->bounds().lower; |
8188 Handle<Type> right_type = expr->right()->bounds().lower; | 8154 Handle<Type> right_type = expr->right()->bounds().lower; |
8189 Handle<Type> combined_type = expr->combined_type(); | 8155 Handle<Type> combined_type = expr->combined_type(); |
8190 Representation combined_rep = Representation::FromType(combined_type); | 8156 Representation combined_rep = Representation::FromType(combined_type); |
8191 Representation left_rep = Representation::FromType(left_type); | 8157 Representation left_rep = Representation::FromType(left_type); |
8192 Representation right_rep = Representation::FromType(right_type); | 8158 Representation right_rep = Representation::FromType(right_type); |
8193 | 8159 |
8194 CHECK_ALIVE(VisitForValue(expr->left())); | 8160 CHECK_ALIVE(VisitForValue(expr->left())); |
8195 CHECK_ALIVE(VisitForValue(expr->right())); | 8161 CHECK_ALIVE(VisitForValue(expr->right())); |
8196 | 8162 |
8197 HValue* context = environment()->context(); | |
8198 HValue* right = Pop(); | 8163 HValue* right = Pop(); |
8199 HValue* left = Pop(); | 8164 HValue* left = Pop(); |
8200 Token::Value op = expr->op(); | 8165 Token::Value op = expr->op(); |
8201 | 8166 |
8202 if (IsLiteralCompareBool(isolate(), left, op, right)) { | 8167 if (IsLiteralCompareBool(isolate(), left, op, right)) { |
8203 HCompareObjectEqAndBranch* result = | 8168 HCompareObjectEqAndBranch* result = |
8204 New<HCompareObjectEqAndBranch>(left, right); | 8169 New<HCompareObjectEqAndBranch>(left, right); |
8205 return ast_context()->ReturnControl(result, expr->id()); | 8170 return ast_context()->ReturnControl(result, expr->id()); |
8206 } | 8171 } |
8207 | 8172 |
(...skipping 17 matching lines...) Expand all Loading... |
8225 // change and thus prefer the general IC code. | 8190 // change and thus prefer the general IC code. |
8226 if (!isolate()->heap()->InNewSpace(*candidate)) { | 8191 if (!isolate()->heap()->InNewSpace(*candidate)) { |
8227 target = candidate; | 8192 target = candidate; |
8228 } | 8193 } |
8229 } | 8194 } |
8230 } | 8195 } |
8231 | 8196 |
8232 // If the target is not null we have found a known global function that is | 8197 // If the target is not null we have found a known global function that is |
8233 // assumed to stay the same for this instanceof. | 8198 // assumed to stay the same for this instanceof. |
8234 if (target.is_null()) { | 8199 if (target.is_null()) { |
8235 HInstanceOf* result = new(zone()) HInstanceOf(context, left, right); | 8200 HInstanceOf* result = New<HInstanceOf>(left, right); |
8236 return ast_context()->ReturnInstruction(result, expr->id()); | 8201 return ast_context()->ReturnInstruction(result, expr->id()); |
8237 } else { | 8202 } else { |
8238 Add<HCheckValue>(right, target); | 8203 Add<HCheckValue>(right, target); |
8239 HInstanceOfKnownGlobal* result = | 8204 HInstanceOfKnownGlobal* result = |
8240 New<HInstanceOfKnownGlobal>(left, target); | 8205 New<HInstanceOfKnownGlobal>(left, target); |
8241 return ast_context()->ReturnInstruction(result, expr->id()); | 8206 return ast_context()->ReturnInstruction(result, expr->id()); |
8242 } | 8207 } |
8243 | 8208 |
8244 // Code below assumes that we don't fall through. | 8209 // Code below assumes that we don't fall through. |
8245 UNREACHABLE(); | 8210 UNREACHABLE(); |
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
8299 } else if (combined_type->Is(Type::String())) { | 8264 } else if (combined_type->Is(Type::String())) { |
8300 BuildCheckHeapObject(left); | 8265 BuildCheckHeapObject(left); |
8301 AddInstruction(HCheckInstanceType::NewIsString(left, zone())); | 8266 AddInstruction(HCheckInstanceType::NewIsString(left, zone())); |
8302 BuildCheckHeapObject(right); | 8267 BuildCheckHeapObject(right); |
8303 AddInstruction(HCheckInstanceType::NewIsString(right, zone())); | 8268 AddInstruction(HCheckInstanceType::NewIsString(right, zone())); |
8304 HStringCompareAndBranch* result = | 8269 HStringCompareAndBranch* result = |
8305 New<HStringCompareAndBranch>(left, right, op); | 8270 New<HStringCompareAndBranch>(left, right, op); |
8306 return ast_context()->ReturnControl(result, expr->id()); | 8271 return ast_context()->ReturnControl(result, expr->id()); |
8307 } else { | 8272 } else { |
8308 if (combined_rep.IsTagged() || combined_rep.IsNone()) { | 8273 if (combined_rep.IsTagged() || combined_rep.IsNone()) { |
8309 HCompareGeneric* result = | 8274 HCompareGeneric* result = New<HCompareGeneric>(left, right, op); |
8310 new(zone()) HCompareGeneric(context, left, right, op); | |
8311 result->set_observed_input_representation(1, left_rep); | 8275 result->set_observed_input_representation(1, left_rep); |
8312 result->set_observed_input_representation(2, right_rep); | 8276 result->set_observed_input_representation(2, right_rep); |
8313 return ast_context()->ReturnInstruction(result, expr->id()); | 8277 return ast_context()->ReturnInstruction(result, expr->id()); |
8314 } else { | 8278 } else { |
8315 HCompareNumericAndBranch* result = | 8279 HCompareNumericAndBranch* result = |
8316 New<HCompareNumericAndBranch>(left, right, op); | 8280 New<HCompareNumericAndBranch>(left, right, op); |
8317 result->set_observed_input_representation(left_rep, right_rep); | 8281 result->set_observed_input_representation(left_rep, right_rep); |
8318 return ast_context()->ReturnControl(result, expr->id()); | 8282 return ast_context()->ReturnControl(result, expr->id()); |
8319 } | 8283 } |
8320 } | 8284 } |
(...skipping 29 matching lines...) Expand all Loading... |
8350 } | 8314 } |
8351 | 8315 |
8352 | 8316 |
8353 HInstruction* HOptimizedGraphBuilder::BuildThisFunction() { | 8317 HInstruction* HOptimizedGraphBuilder::BuildThisFunction() { |
8354 // If we share optimized code between different closures, the | 8318 // If we share optimized code between different closures, the |
8355 // this-function is not a constant, except inside an inlined body. | 8319 // this-function is not a constant, except inside an inlined body. |
8356 if (function_state()->outer() != NULL) { | 8320 if (function_state()->outer() != NULL) { |
8357 return New<HConstant>( | 8321 return New<HConstant>( |
8358 function_state()->compilation_info()->closure()); | 8322 function_state()->compilation_info()->closure()); |
8359 } else { | 8323 } else { |
8360 return new(zone()) HThisFunction; | 8324 return New<HThisFunction>(); |
8361 } | 8325 } |
8362 } | 8326 } |
8363 | 8327 |
8364 | 8328 |
8365 HInstruction* HOptimizedGraphBuilder::BuildFastLiteral( | 8329 HInstruction* HOptimizedGraphBuilder::BuildFastLiteral( |
8366 Handle<JSObject> boilerplate_object, | 8330 Handle<JSObject> boilerplate_object, |
8367 AllocationSiteContext* site_context) { | 8331 AllocationSiteContext* site_context) { |
8368 NoObservableSideEffectsScope no_effects(this); | 8332 NoObservableSideEffectsScope no_effects(this); |
8369 InstanceType instance_type = boilerplate_object->map()->instance_type(); | 8333 InstanceType instance_type = boilerplate_object->map()->instance_type(); |
8370 ASSERT(instance_type == JS_ARRAY_TYPE || instance_type == JS_OBJECT_TYPE); | 8334 ASSERT(instance_type == JS_ARRAY_TYPE || instance_type == JS_OBJECT_TYPE); |
(...skipping 399 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
8770 New<HHasInstanceTypeAndBranch>(value, JS_FUNCTION_TYPE); | 8734 New<HHasInstanceTypeAndBranch>(value, JS_FUNCTION_TYPE); |
8771 return ast_context()->ReturnControl(result, call->id()); | 8735 return ast_context()->ReturnControl(result, call->id()); |
8772 } | 8736 } |
8773 | 8737 |
8774 | 8738 |
8775 void HOptimizedGraphBuilder::GenerateHasCachedArrayIndex(CallRuntime* call) { | 8739 void HOptimizedGraphBuilder::GenerateHasCachedArrayIndex(CallRuntime* call) { |
8776 ASSERT(call->arguments()->length() == 1); | 8740 ASSERT(call->arguments()->length() == 1); |
8777 CHECK_ALIVE(VisitForValue(call->arguments()->at(0))); | 8741 CHECK_ALIVE(VisitForValue(call->arguments()->at(0))); |
8778 HValue* value = Pop(); | 8742 HValue* value = Pop(); |
8779 HHasCachedArrayIndexAndBranch* result = | 8743 HHasCachedArrayIndexAndBranch* result = |
8780 new(zone()) HHasCachedArrayIndexAndBranch(value); | 8744 New<HHasCachedArrayIndexAndBranch>(value); |
8781 return ast_context()->ReturnControl(result, call->id()); | 8745 return ast_context()->ReturnControl(result, call->id()); |
8782 } | 8746 } |
8783 | 8747 |
8784 | 8748 |
8785 void HOptimizedGraphBuilder::GenerateIsArray(CallRuntime* call) { | 8749 void HOptimizedGraphBuilder::GenerateIsArray(CallRuntime* call) { |
8786 ASSERT(call->arguments()->length() == 1); | 8750 ASSERT(call->arguments()->length() == 1); |
8787 CHECK_ALIVE(VisitForValue(call->arguments()->at(0))); | 8751 CHECK_ALIVE(VisitForValue(call->arguments()->at(0))); |
8788 HValue* value = Pop(); | 8752 HValue* value = Pop(); |
8789 HHasInstanceTypeAndBranch* result = | 8753 HHasInstanceTypeAndBranch* result = |
8790 New<HHasInstanceTypeAndBranch>(value, JS_ARRAY_TYPE); | 8754 New<HHasInstanceTypeAndBranch>(value, JS_ARRAY_TYPE); |
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
8834 // Support for construct call checks. | 8798 // Support for construct call checks. |
8835 void HOptimizedGraphBuilder::GenerateIsConstructCall(CallRuntime* call) { | 8799 void HOptimizedGraphBuilder::GenerateIsConstructCall(CallRuntime* call) { |
8836 ASSERT(call->arguments()->length() == 0); | 8800 ASSERT(call->arguments()->length() == 0); |
8837 if (function_state()->outer() != NULL) { | 8801 if (function_state()->outer() != NULL) { |
8838 // We are generating graph for inlined function. | 8802 // We are generating graph for inlined function. |
8839 HValue* value = function_state()->inlining_kind() == CONSTRUCT_CALL_RETURN | 8803 HValue* value = function_state()->inlining_kind() == CONSTRUCT_CALL_RETURN |
8840 ? graph()->GetConstantTrue() | 8804 ? graph()->GetConstantTrue() |
8841 : graph()->GetConstantFalse(); | 8805 : graph()->GetConstantFalse(); |
8842 return ast_context()->ReturnValue(value); | 8806 return ast_context()->ReturnValue(value); |
8843 } else { | 8807 } else { |
8844 return ast_context()->ReturnControl(new(zone()) HIsConstructCallAndBranch, | 8808 return ast_context()->ReturnControl(New<HIsConstructCallAndBranch>(), |
8845 call->id()); | 8809 call->id()); |
8846 } | 8810 } |
8847 } | 8811 } |
8848 | 8812 |
8849 | 8813 |
8850 // Support for arguments.length and arguments[?]. | 8814 // Support for arguments.length and arguments[?]. |
8851 void HOptimizedGraphBuilder::GenerateArgumentsLength(CallRuntime* call) { | 8815 void HOptimizedGraphBuilder::GenerateArgumentsLength(CallRuntime* call) { |
8852 // Our implementation of arguments (based on this stack frame or an | 8816 // Our implementation of arguments (based on this stack frame or an |
8853 // adapter below it) does not work for inlined functions. This runtime | 8817 // adapter below it) does not work for inlined functions. This runtime |
8854 // function is blacklisted by AstNode::IsInlineable. | 8818 // function is blacklisted by AstNode::IsInlineable. |
8855 ASSERT(function_state()->outer() == NULL); | 8819 ASSERT(function_state()->outer() == NULL); |
8856 ASSERT(call->arguments()->length() == 0); | 8820 ASSERT(call->arguments()->length() == 0); |
8857 HInstruction* elements = Add<HArgumentsElements>(false); | 8821 HInstruction* elements = Add<HArgumentsElements>(false); |
8858 HArgumentsLength* result = New<HArgumentsLength>(elements); | 8822 HArgumentsLength* result = New<HArgumentsLength>(elements); |
8859 return ast_context()->ReturnInstruction(result, call->id()); | 8823 return ast_context()->ReturnInstruction(result, call->id()); |
8860 } | 8824 } |
8861 | 8825 |
8862 | 8826 |
8863 void HOptimizedGraphBuilder::GenerateArguments(CallRuntime* call) { | 8827 void HOptimizedGraphBuilder::GenerateArguments(CallRuntime* call) { |
8864 // Our implementation of arguments (based on this stack frame or an | 8828 // Our implementation of arguments (based on this stack frame or an |
8865 // adapter below it) does not work for inlined functions. This runtime | 8829 // adapter below it) does not work for inlined functions. This runtime |
8866 // function is blacklisted by AstNode::IsInlineable. | 8830 // function is blacklisted by AstNode::IsInlineable. |
8867 ASSERT(function_state()->outer() == NULL); | 8831 ASSERT(function_state()->outer() == NULL); |
8868 ASSERT(call->arguments()->length() == 1); | 8832 ASSERT(call->arguments()->length() == 1); |
8869 CHECK_ALIVE(VisitForValue(call->arguments()->at(0))); | 8833 CHECK_ALIVE(VisitForValue(call->arguments()->at(0))); |
8870 HValue* index = Pop(); | 8834 HValue* index = Pop(); |
8871 HInstruction* elements = Add<HArgumentsElements>(false); | 8835 HInstruction* elements = Add<HArgumentsElements>(false); |
8872 HInstruction* length = Add<HArgumentsLength>(elements); | 8836 HInstruction* length = Add<HArgumentsLength>(elements); |
8873 HInstruction* checked_index = Add<HBoundsCheck>(index, length); | 8837 HInstruction* checked_index = Add<HBoundsCheck>(index, length); |
8874 HAccessArgumentsAt* result = | 8838 HAccessArgumentsAt* result = New<HAccessArgumentsAt>( |
8875 new(zone()) HAccessArgumentsAt(elements, length, checked_index); | 8839 elements, length, checked_index); |
8876 return ast_context()->ReturnInstruction(result, call->id()); | 8840 return ast_context()->ReturnInstruction(result, call->id()); |
8877 } | 8841 } |
8878 | 8842 |
8879 | 8843 |
8880 // Support for accessing the class and value fields of an object. | 8844 // Support for accessing the class and value fields of an object. |
8881 void HOptimizedGraphBuilder::GenerateClassOf(CallRuntime* call) { | 8845 void HOptimizedGraphBuilder::GenerateClassOf(CallRuntime* call) { |
8882 // The special form detected by IsClassOfTest is detected before we get here | 8846 // The special form detected by IsClassOfTest is detected before we get here |
8883 // and does not cause a bailout. | 8847 // and does not cause a bailout. |
8884 return Bailout(kInlinedRuntimeFunctionClassOf); | 8848 return Bailout(kInlinedRuntimeFunctionClassOf); |
8885 } | 8849 } |
8886 | 8850 |
8887 | 8851 |
8888 void HOptimizedGraphBuilder::GenerateValueOf(CallRuntime* call) { | 8852 void HOptimizedGraphBuilder::GenerateValueOf(CallRuntime* call) { |
8889 ASSERT(call->arguments()->length() == 1); | 8853 ASSERT(call->arguments()->length() == 1); |
8890 CHECK_ALIVE(VisitForValue(call->arguments()->at(0))); | 8854 CHECK_ALIVE(VisitForValue(call->arguments()->at(0))); |
8891 HValue* value = Pop(); | 8855 HValue* value = Pop(); |
8892 HValueOf* result = new(zone()) HValueOf(value); | 8856 HValueOf* result = New<HValueOf>(value); |
8893 return ast_context()->ReturnInstruction(result, call->id()); | 8857 return ast_context()->ReturnInstruction(result, call->id()); |
8894 } | 8858 } |
8895 | 8859 |
8896 | 8860 |
8897 void HOptimizedGraphBuilder::GenerateDateField(CallRuntime* call) { | 8861 void HOptimizedGraphBuilder::GenerateDateField(CallRuntime* call) { |
8898 ASSERT(call->arguments()->length() == 2); | 8862 ASSERT(call->arguments()->length() == 2); |
8899 ASSERT_NE(NULL, call->arguments()->at(1)->AsLiteral()); | 8863 ASSERT_NE(NULL, call->arguments()->at(1)->AsLiteral()); |
8900 Smi* index = Smi::cast(*(call->arguments()->at(1)->AsLiteral()->value())); | 8864 Smi* index = Smi::cast(*(call->arguments()->at(1)->AsLiteral()->value())); |
8901 CHECK_ALIVE(VisitForValue(call->arguments()->at(0))); | 8865 CHECK_ALIVE(VisitForValue(call->arguments()->at(0))); |
8902 HValue* date = Pop(); | 8866 HValue* date = Pop(); |
8903 HDateField* result = new(zone()) HDateField(date, index); | 8867 HDateField* result = New<HDateField>(date, index); |
8904 return ast_context()->ReturnInstruction(result, call->id()); | 8868 return ast_context()->ReturnInstruction(result, call->id()); |
8905 } | 8869 } |
8906 | 8870 |
8907 | 8871 |
8908 void HOptimizedGraphBuilder::GenerateOneByteSeqStringSetChar( | 8872 void HOptimizedGraphBuilder::GenerateOneByteSeqStringSetChar( |
8909 CallRuntime* call) { | 8873 CallRuntime* call) { |
8910 ASSERT(call->arguments()->length() == 3); | 8874 ASSERT(call->arguments()->length() == 3); |
8911 CHECK_ALIVE(VisitForValue(call->arguments()->at(0))); | 8875 CHECK_ALIVE(VisitForValue(call->arguments()->at(0))); |
8912 CHECK_ALIVE(VisitForValue(call->arguments()->at(1))); | 8876 CHECK_ALIVE(VisitForValue(call->arguments()->at(1))); |
8913 CHECK_ALIVE(VisitForValue(call->arguments()->at(2))); | 8877 CHECK_ALIVE(VisitForValue(call->arguments()->at(2))); |
8914 HValue* value = Pop(); | 8878 HValue* value = Pop(); |
8915 HValue* index = Pop(); | 8879 HValue* index = Pop(); |
8916 HValue* string = Pop(); | 8880 HValue* string = Pop(); |
8917 HSeqStringSetChar* result = new(zone()) HSeqStringSetChar( | 8881 HSeqStringSetChar* result = New<HSeqStringSetChar>( |
8918 String::ONE_BYTE_ENCODING, string, index, value); | 8882 String::ONE_BYTE_ENCODING, string, index, value); |
8919 return ast_context()->ReturnInstruction(result, call->id()); | 8883 return ast_context()->ReturnInstruction(result, call->id()); |
8920 } | 8884 } |
8921 | 8885 |
8922 | 8886 |
8923 void HOptimizedGraphBuilder::GenerateTwoByteSeqStringSetChar( | 8887 void HOptimizedGraphBuilder::GenerateTwoByteSeqStringSetChar( |
8924 CallRuntime* call) { | 8888 CallRuntime* call) { |
8925 ASSERT(call->arguments()->length() == 3); | 8889 ASSERT(call->arguments()->length() == 3); |
8926 CHECK_ALIVE(VisitForValue(call->arguments()->at(0))); | 8890 CHECK_ALIVE(VisitForValue(call->arguments()->at(0))); |
8927 CHECK_ALIVE(VisitForValue(call->arguments()->at(1))); | 8891 CHECK_ALIVE(VisitForValue(call->arguments()->at(1))); |
8928 CHECK_ALIVE(VisitForValue(call->arguments()->at(2))); | 8892 CHECK_ALIVE(VisitForValue(call->arguments()->at(2))); |
8929 HValue* value = Pop(); | 8893 HValue* value = Pop(); |
8930 HValue* index = Pop(); | 8894 HValue* index = Pop(); |
8931 HValue* string = Pop(); | 8895 HValue* string = Pop(); |
8932 HSeqStringSetChar* result = new(zone()) HSeqStringSetChar( | 8896 HSeqStringSetChar* result = New<HSeqStringSetChar>( |
8933 String::TWO_BYTE_ENCODING, string, index, value); | 8897 String::TWO_BYTE_ENCODING, string, index, value); |
8934 return ast_context()->ReturnInstruction(result, call->id()); | 8898 return ast_context()->ReturnInstruction(result, call->id()); |
8935 } | 8899 } |
8936 | 8900 |
8937 | 8901 |
8938 void HOptimizedGraphBuilder::GenerateSetValueOf(CallRuntime* call) { | 8902 void HOptimizedGraphBuilder::GenerateSetValueOf(CallRuntime* call) { |
8939 ASSERT(call->arguments()->length() == 2); | 8903 ASSERT(call->arguments()->length() == 2); |
8940 CHECK_ALIVE(VisitForValue(call->arguments()->at(0))); | 8904 CHECK_ALIVE(VisitForValue(call->arguments()->at(0))); |
8941 CHECK_ALIVE(VisitForValue(call->arguments()->at(1))); | 8905 CHECK_ALIVE(VisitForValue(call->arguments()->at(1))); |
8942 HValue* value = Pop(); | 8906 HValue* value = Pop(); |
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
8980 HInstruction* result = BuildStringCharCodeAt(string, index); | 8944 HInstruction* result = BuildStringCharCodeAt(string, index); |
8981 return ast_context()->ReturnInstruction(result, call->id()); | 8945 return ast_context()->ReturnInstruction(result, call->id()); |
8982 } | 8946 } |
8983 | 8947 |
8984 | 8948 |
8985 // Fast support for string.charAt(n) and string[n]. | 8949 // Fast support for string.charAt(n) and string[n]. |
8986 void HOptimizedGraphBuilder::GenerateStringCharFromCode(CallRuntime* call) { | 8950 void HOptimizedGraphBuilder::GenerateStringCharFromCode(CallRuntime* call) { |
8987 ASSERT(call->arguments()->length() == 1); | 8951 ASSERT(call->arguments()->length() == 1); |
8988 CHECK_ALIVE(VisitForValue(call->arguments()->at(0))); | 8952 CHECK_ALIVE(VisitForValue(call->arguments()->at(0))); |
8989 HValue* char_code = Pop(); | 8953 HValue* char_code = Pop(); |
8990 HInstruction* result = New<HStringCharFromCode>(char_code); | 8954 HInstruction* result = NewUncasted<HStringCharFromCode>(char_code); |
8991 return ast_context()->ReturnInstruction(result, call->id()); | 8955 return ast_context()->ReturnInstruction(result, call->id()); |
8992 } | 8956 } |
8993 | 8957 |
8994 | 8958 |
8995 // Fast support for string.charAt(n) and string[n]. | 8959 // Fast support for string.charAt(n) and string[n]. |
8996 void HOptimizedGraphBuilder::GenerateStringCharAt(CallRuntime* call) { | 8960 void HOptimizedGraphBuilder::GenerateStringCharAt(CallRuntime* call) { |
8997 ASSERT(call->arguments()->length() == 2); | 8961 ASSERT(call->arguments()->length() == 2); |
8998 CHECK_ALIVE(VisitForValue(call->arguments()->at(0))); | 8962 CHECK_ALIVE(VisitForValue(call->arguments()->at(0))); |
8999 CHECK_ALIVE(VisitForValue(call->arguments()->at(1))); | 8963 CHECK_ALIVE(VisitForValue(call->arguments()->at(1))); |
9000 HValue* index = Pop(); | 8964 HValue* index = Pop(); |
9001 HValue* string = Pop(); | 8965 HValue* string = Pop(); |
9002 HInstruction* char_code = BuildStringCharCodeAt(string, index); | 8966 HInstruction* char_code = BuildStringCharCodeAt(string, index); |
9003 AddInstruction(char_code); | 8967 AddInstruction(char_code); |
9004 HInstruction* result = New<HStringCharFromCode>(char_code); | 8968 HInstruction* result = NewUncasted<HStringCharFromCode>(char_code); |
9005 return ast_context()->ReturnInstruction(result, call->id()); | 8969 return ast_context()->ReturnInstruction(result, call->id()); |
9006 } | 8970 } |
9007 | 8971 |
9008 | 8972 |
9009 // Fast support for object equality testing. | 8973 // Fast support for object equality testing. |
9010 void HOptimizedGraphBuilder::GenerateObjectEquals(CallRuntime* call) { | 8974 void HOptimizedGraphBuilder::GenerateObjectEquals(CallRuntime* call) { |
9011 ASSERT(call->arguments()->length() == 2); | 8975 ASSERT(call->arguments()->length() == 2); |
9012 CHECK_ALIVE(VisitForValue(call->arguments()->at(0))); | 8976 CHECK_ALIVE(VisitForValue(call->arguments()->at(0))); |
9013 CHECK_ALIVE(VisitForValue(call->arguments()->at(1))); | 8977 CHECK_ALIVE(VisitForValue(call->arguments()->at(1))); |
9014 HValue* right = Pop(); | 8978 HValue* right = Pop(); |
9015 HValue* left = Pop(); | 8979 HValue* left = Pop(); |
9016 HCompareObjectEqAndBranch* result = | 8980 HCompareObjectEqAndBranch* result = |
9017 New<HCompareObjectEqAndBranch>(left, right); | 8981 New<HCompareObjectEqAndBranch>(left, right); |
9018 return ast_context()->ReturnControl(result, call->id()); | 8982 return ast_context()->ReturnControl(result, call->id()); |
9019 } | 8983 } |
9020 | 8984 |
9021 | 8985 |
9022 void HOptimizedGraphBuilder::GenerateLog(CallRuntime* call) { | 8986 void HOptimizedGraphBuilder::GenerateLog(CallRuntime* call) { |
9023 // %_Log is ignored in optimized code. | 8987 // %_Log is ignored in optimized code. |
9024 return ast_context()->ReturnValue(graph()->GetConstantUndefined()); | 8988 return ast_context()->ReturnValue(graph()->GetConstantUndefined()); |
9025 } | 8989 } |
9026 | 8990 |
9027 | 8991 |
9028 // Fast support for Math.random(). | 8992 // Fast support for Math.random(). |
9029 void HOptimizedGraphBuilder::GenerateRandomHeapNumber(CallRuntime* call) { | 8993 void HOptimizedGraphBuilder::GenerateRandomHeapNumber(CallRuntime* call) { |
9030 HGlobalObject* global_object = Add<HGlobalObject>(); | 8994 HGlobalObject* global_object = Add<HGlobalObject>(); |
9031 HRandom* result = new(zone()) HRandom(global_object); | 8995 HRandom* result = New<HRandom>(global_object); |
9032 return ast_context()->ReturnInstruction(result, call->id()); | 8996 return ast_context()->ReturnInstruction(result, call->id()); |
9033 } | 8997 } |
9034 | 8998 |
9035 | 8999 |
9036 // Fast support for StringAdd. | 9000 // Fast support for StringAdd. |
9037 void HOptimizedGraphBuilder::GenerateStringAdd(CallRuntime* call) { | 9001 void HOptimizedGraphBuilder::GenerateStringAdd(CallRuntime* call) { |
9038 ASSERT_EQ(2, call->arguments()->length()); | 9002 ASSERT_EQ(2, call->arguments()->length()); |
9039 CHECK_ALIVE(VisitForValue(call->arguments()->at(0))); | 9003 CHECK_ALIVE(VisitForValue(call->arguments()->at(0))); |
9040 CHECK_ALIVE(VisitForValue(call->arguments()->at(1))); | 9004 CHECK_ALIVE(VisitForValue(call->arguments()->at(1))); |
9041 HValue* right = Pop(); | 9005 HValue* right = Pop(); |
(...skipping 101 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
9143 } | 9107 } |
9144 | 9108 |
9145 | 9109 |
9146 // Fast call to math functions. | 9110 // Fast call to math functions. |
9147 void HOptimizedGraphBuilder::GenerateMathPow(CallRuntime* call) { | 9111 void HOptimizedGraphBuilder::GenerateMathPow(CallRuntime* call) { |
9148 ASSERT_EQ(2, call->arguments()->length()); | 9112 ASSERT_EQ(2, call->arguments()->length()); |
9149 CHECK_ALIVE(VisitForValue(call->arguments()->at(0))); | 9113 CHECK_ALIVE(VisitForValue(call->arguments()->at(0))); |
9150 CHECK_ALIVE(VisitForValue(call->arguments()->at(1))); | 9114 CHECK_ALIVE(VisitForValue(call->arguments()->at(1))); |
9151 HValue* right = Pop(); | 9115 HValue* right = Pop(); |
9152 HValue* left = Pop(); | 9116 HValue* left = Pop(); |
9153 HInstruction* result = HPower::New(zone(), context(), left, right); | 9117 HInstruction* result = NewUncasted<HPower>(left, right); |
9154 return ast_context()->ReturnInstruction(result, call->id()); | 9118 return ast_context()->ReturnInstruction(result, call->id()); |
9155 } | 9119 } |
9156 | 9120 |
9157 | 9121 |
9158 void HOptimizedGraphBuilder::GenerateMathSin(CallRuntime* call) { | 9122 void HOptimizedGraphBuilder::GenerateMathSin(CallRuntime* call) { |
9159 ASSERT_EQ(1, call->arguments()->length()); | 9123 ASSERT_EQ(1, call->arguments()->length()); |
9160 CHECK_ALIVE(VisitArgumentList(call->arguments())); | 9124 CHECK_ALIVE(VisitArgumentList(call->arguments())); |
9161 HCallStub* result = New<HCallStub>(CodeStub::TranscendentalCache, 1); | 9125 HCallStub* result = New<HCallStub>(CodeStub::TranscendentalCache, 1); |
9162 result->set_transcendental_type(TranscendentalCache::SIN); | 9126 result->set_transcendental_type(TranscendentalCache::SIN); |
9163 Drop(1); | 9127 Drop(1); |
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
9207 // Check whether two RegExps are equivalent | 9171 // Check whether two RegExps are equivalent |
9208 void HOptimizedGraphBuilder::GenerateIsRegExpEquivalent(CallRuntime* call) { | 9172 void HOptimizedGraphBuilder::GenerateIsRegExpEquivalent(CallRuntime* call) { |
9209 return Bailout(kInlinedRuntimeFunctionIsRegExpEquivalent); | 9173 return Bailout(kInlinedRuntimeFunctionIsRegExpEquivalent); |
9210 } | 9174 } |
9211 | 9175 |
9212 | 9176 |
9213 void HOptimizedGraphBuilder::GenerateGetCachedArrayIndex(CallRuntime* call) { | 9177 void HOptimizedGraphBuilder::GenerateGetCachedArrayIndex(CallRuntime* call) { |
9214 ASSERT(call->arguments()->length() == 1); | 9178 ASSERT(call->arguments()->length() == 1); |
9215 CHECK_ALIVE(VisitForValue(call->arguments()->at(0))); | 9179 CHECK_ALIVE(VisitForValue(call->arguments()->at(0))); |
9216 HValue* value = Pop(); | 9180 HValue* value = Pop(); |
9217 HGetCachedArrayIndex* result = new(zone()) HGetCachedArrayIndex(value); | 9181 HGetCachedArrayIndex* result = New<HGetCachedArrayIndex>(value); |
9218 return ast_context()->ReturnInstruction(result, call->id()); | 9182 return ast_context()->ReturnInstruction(result, call->id()); |
9219 } | 9183 } |
9220 | 9184 |
9221 | 9185 |
9222 void HOptimizedGraphBuilder::GenerateFastAsciiArrayJoin(CallRuntime* call) { | 9186 void HOptimizedGraphBuilder::GenerateFastAsciiArrayJoin(CallRuntime* call) { |
9223 return Bailout(kInlinedRuntimeFunctionFastAsciiArrayJoin); | 9187 return Bailout(kInlinedRuntimeFunctionFastAsciiArrayJoin); |
9224 } | 9188 } |
9225 | 9189 |
9226 | 9190 |
9227 // Support for generators. | 9191 // Support for generators. |
9228 void HOptimizedGraphBuilder::GenerateGeneratorNext(CallRuntime* call) { | 9192 void HOptimizedGraphBuilder::GenerateGeneratorNext(CallRuntime* call) { |
9229 return Bailout(kInlinedRuntimeFunctionGeneratorNext); | 9193 return Bailout(kInlinedRuntimeFunctionGeneratorNext); |
9230 } | 9194 } |
9231 | 9195 |
9232 | 9196 |
9233 void HOptimizedGraphBuilder::GenerateGeneratorThrow(CallRuntime* call) { | 9197 void HOptimizedGraphBuilder::GenerateGeneratorThrow(CallRuntime* call) { |
9234 return Bailout(kInlinedRuntimeFunctionGeneratorThrow); | 9198 return Bailout(kInlinedRuntimeFunctionGeneratorThrow); |
9235 } | 9199 } |
9236 | 9200 |
9237 | 9201 |
9238 void HOptimizedGraphBuilder::GenerateDebugBreakInOptimizedCode( | 9202 void HOptimizedGraphBuilder::GenerateDebugBreakInOptimizedCode( |
9239 CallRuntime* call) { | 9203 CallRuntime* call) { |
9240 AddInstruction(new(zone()) HDebugBreak()); | 9204 Add<HDebugBreak>(); |
9241 return ast_context()->ReturnValue(graph()->GetConstant0()); | 9205 return ast_context()->ReturnValue(graph()->GetConstant0()); |
9242 } | 9206 } |
9243 | 9207 |
9244 | 9208 |
9245 #undef CHECK_BAILOUT | 9209 #undef CHECK_BAILOUT |
9246 #undef CHECK_ALIVE | 9210 #undef CHECK_ALIVE |
9247 | 9211 |
9248 | 9212 |
9249 HEnvironment::HEnvironment(HEnvironment* outer, | 9213 HEnvironment::HEnvironment(HEnvironment* outer, |
9250 Scope* scope, | 9214 Scope* scope, |
(...skipping 597 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
9848 if (ShouldProduceTraceOutput()) { | 9812 if (ShouldProduceTraceOutput()) { |
9849 isolate()->GetHTracer()->TraceHydrogen(name(), graph_); | 9813 isolate()->GetHTracer()->TraceHydrogen(name(), graph_); |
9850 } | 9814 } |
9851 | 9815 |
9852 #ifdef DEBUG | 9816 #ifdef DEBUG |
9853 graph_->Verify(false); // No full verify. | 9817 graph_->Verify(false); // No full verify. |
9854 #endif | 9818 #endif |
9855 } | 9819 } |
9856 | 9820 |
9857 } } // namespace v8::internal | 9821 } } // namespace v8::internal |
OLD | NEW |