Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(424)

Side by Side Diff: src/hydrogen.cc

Issue 196133017: Experimental parser: merge r19949 (Closed) Base URL: https://v8.googlecode.com/svn/branches/experimental/parser
Patch Set: Created 6 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « src/hydrogen.h ('k') | src/hydrogen-bce.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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 30 matching lines...) Expand all
41 #include "hydrogen-dce.h" 41 #include "hydrogen-dce.h"
42 #include "hydrogen-dehoist.h" 42 #include "hydrogen-dehoist.h"
43 #include "hydrogen-environment-liveness.h" 43 #include "hydrogen-environment-liveness.h"
44 #include "hydrogen-escape-analysis.h" 44 #include "hydrogen-escape-analysis.h"
45 #include "hydrogen-infer-representation.h" 45 #include "hydrogen-infer-representation.h"
46 #include "hydrogen-infer-types.h" 46 #include "hydrogen-infer-types.h"
47 #include "hydrogen-load-elimination.h" 47 #include "hydrogen-load-elimination.h"
48 #include "hydrogen-gvn.h" 48 #include "hydrogen-gvn.h"
49 #include "hydrogen-mark-deoptimize.h" 49 #include "hydrogen-mark-deoptimize.h"
50 #include "hydrogen-mark-unreachable.h" 50 #include "hydrogen-mark-unreachable.h"
51 #include "hydrogen-minus-zero.h"
52 #include "hydrogen-osr.h" 51 #include "hydrogen-osr.h"
53 #include "hydrogen-range-analysis.h" 52 #include "hydrogen-range-analysis.h"
54 #include "hydrogen-redundant-phi.h" 53 #include "hydrogen-redundant-phi.h"
55 #include "hydrogen-removable-simulates.h" 54 #include "hydrogen-removable-simulates.h"
56 #include "hydrogen-representation-changes.h" 55 #include "hydrogen-representation-changes.h"
57 #include "hydrogen-sce.h" 56 #include "hydrogen-sce.h"
58 #include "hydrogen-uint32-analysis.h" 57 #include "hydrogen-uint32-analysis.h"
59 #include "lithium-allocator.h" 58 #include "lithium-allocator.h"
60 #include "parser.h" 59 #include "parser.h"
61 #include "runtime.h" 60 #include "runtime.h"
(...skipping 639 matching lines...) Expand 10 before | Expand all | Expand 10 after
701 } 700 }
702 701
703 702
704 #define DEFINE_GET_CONSTANT(Name, name, htype, boolean_value) \ 703 #define DEFINE_GET_CONSTANT(Name, name, htype, boolean_value) \
705 HConstant* HGraph::GetConstant##Name() { \ 704 HConstant* HGraph::GetConstant##Name() { \
706 if (!constant_##name##_.is_set()) { \ 705 if (!constant_##name##_.is_set()) { \
707 HConstant* constant = new(zone()) HConstant( \ 706 HConstant* constant = new(zone()) HConstant( \
708 Unique<Object>::CreateImmovable(isolate()->factory()->name##_value()), \ 707 Unique<Object>::CreateImmovable(isolate()->factory()->name##_value()), \
709 Representation::Tagged(), \ 708 Representation::Tagged(), \
710 htype, \ 709 htype, \
710 true, \
711 boolean_value, \
711 false, \ 712 false, \
712 true, \ 713 ODDBALL_TYPE); \
713 false, \
714 boolean_value); \
715 constant->InsertAfter(entry_block()->first()); \ 714 constant->InsertAfter(entry_block()->first()); \
716 constant_##name##_.set(constant); \ 715 constant_##name##_.set(constant); \
717 } \ 716 } \
718 return ReinsertConstantIfNecessary(constant_##name##_.get()); \ 717 return ReinsertConstantIfNecessary(constant_##name##_.get()); \
719 } 718 }
720 719
721 720
722 DEFINE_GET_CONSTANT(Undefined, undefined, HType::Tagged(), false) 721 DEFINE_GET_CONSTANT(Undefined, undefined, HType::Tagged(), false)
723 DEFINE_GET_CONSTANT(True, true, HType::Boolean(), true) 722 DEFINE_GET_CONSTANT(True, true, HType::Boolean(), true)
724 DEFINE_GET_CONSTANT(False, false, HType::Boolean(), false) 723 DEFINE_GET_CONSTANT(False, false, HType::Boolean(), false)
(...skipping 551 matching lines...) Expand 10 before | Expand all | Expand 10 after
1276 } 1275 }
1277 1276
1278 1277
1279 HValue* HGraphBuilder::BuildWrapReceiver(HValue* object, HValue* function) { 1278 HValue* HGraphBuilder::BuildWrapReceiver(HValue* object, HValue* function) {
1280 if (object->type().IsJSObject()) return object; 1279 if (object->type().IsJSObject()) return object;
1281 if (function->IsConstant() && 1280 if (function->IsConstant() &&
1282 HConstant::cast(function)->handle(isolate())->IsJSFunction()) { 1281 HConstant::cast(function)->handle(isolate())->IsJSFunction()) {
1283 Handle<JSFunction> f = Handle<JSFunction>::cast( 1282 Handle<JSFunction> f = Handle<JSFunction>::cast(
1284 HConstant::cast(function)->handle(isolate())); 1283 HConstant::cast(function)->handle(isolate()));
1285 SharedFunctionInfo* shared = f->shared(); 1284 SharedFunctionInfo* shared = f->shared();
1286 if (!shared->is_classic_mode() || shared->native()) return object; 1285 if (shared->strict_mode() == STRICT || shared->native()) return object;
1287 } 1286 }
1288 return Add<HWrapReceiver>(object, function); 1287 return Add<HWrapReceiver>(object, function);
1289 } 1288 }
1290 1289
1291 1290
1292 HValue* HGraphBuilder::BuildCheckForCapacityGrow( 1291 HValue* HGraphBuilder::BuildCheckForCapacityGrow(
1293 HValue* object, 1292 HValue* object,
1294 HValue* elements, 1293 HValue* elements,
1295 ElementsKind kind, 1294 ElementsKind kind,
1296 HValue* length, 1295 HValue* length,
(...skipping 2588 matching lines...) Expand 10 before | Expand all | Expand 10 after
3885 } 3884 }
3886 3885
3887 3886
3888 void HOptimizedGraphBuilder::VisitForTypeOf(Expression* expr) { 3887 void HOptimizedGraphBuilder::VisitForTypeOf(Expression* expr) {
3889 ValueContext for_value(this, ARGUMENTS_NOT_ALLOWED); 3888 ValueContext for_value(this, ARGUMENTS_NOT_ALLOWED);
3890 for_value.set_for_typeof(true); 3889 for_value.set_for_typeof(true);
3891 Visit(expr); 3890 Visit(expr);
3892 } 3891 }
3893 3892
3894 3893
3895
3896 void HOptimizedGraphBuilder::VisitForControl(Expression* expr, 3894 void HOptimizedGraphBuilder::VisitForControl(Expression* expr,
3897 HBasicBlock* true_block, 3895 HBasicBlock* true_block,
3898 HBasicBlock* false_block) { 3896 HBasicBlock* false_block) {
3899 TestContext for_test(this, expr, true_block, false_block); 3897 TestContext for_test(this, expr, true_block, false_block);
3900 Visit(expr); 3898 Visit(expr);
3901 } 3899 }
3902 3900
3903 3901
3904 void HOptimizedGraphBuilder::VisitArgument(Expression* expr) {
3905 CHECK_ALIVE(VisitForValue(expr));
3906 Push(Add<HPushArgument>(Pop()));
3907 }
3908
3909
3910 void HOptimizedGraphBuilder::VisitArgumentList(
3911 ZoneList<Expression*>* arguments) {
3912 for (int i = 0; i < arguments->length(); i++) {
3913 CHECK_ALIVE(VisitArgument(arguments->at(i)));
3914 }
3915 }
3916
3917
3918 void HOptimizedGraphBuilder::VisitExpressions( 3902 void HOptimizedGraphBuilder::VisitExpressions(
3919 ZoneList<Expression*>* exprs) { 3903 ZoneList<Expression*>* exprs) {
3920 for (int i = 0; i < exprs->length(); ++i) { 3904 for (int i = 0; i < exprs->length(); ++i) {
3921 CHECK_ALIVE(VisitForValue(exprs->at(i))); 3905 CHECK_ALIVE(VisitForValue(exprs->at(i)));
3922 } 3906 }
3923 } 3907 }
3924 3908
3925 3909
3926 bool HOptimizedGraphBuilder::BuildGraph() { 3910 bool HOptimizedGraphBuilder::BuildGraph() {
3927 if (current_info()->function()->is_generator()) { 3911 if (current_info()->function()->is_generator()) {
(...skipping 129 matching lines...) Expand 10 before | Expand all | Expand 10 after
4057 // will not remove semantically meaningful ToInt32 operations e.g. BIT_OR with 4041 // will not remove semantically meaningful ToInt32 operations e.g. BIT_OR with
4058 // zero. 4042 // zero.
4059 if (FLAG_opt_safe_uint32_operations) Run<HUint32AnalysisPhase>(); 4043 if (FLAG_opt_safe_uint32_operations) Run<HUint32AnalysisPhase>();
4060 4044
4061 if (FLAG_use_canonicalizing) Run<HCanonicalizePhase>(); 4045 if (FLAG_use_canonicalizing) Run<HCanonicalizePhase>();
4062 4046
4063 if (FLAG_use_gvn) Run<HGlobalValueNumberingPhase>(); 4047 if (FLAG_use_gvn) Run<HGlobalValueNumberingPhase>();
4064 4048
4065 if (FLAG_check_elimination) Run<HCheckEliminationPhase>(); 4049 if (FLAG_check_elimination) Run<HCheckEliminationPhase>();
4066 4050
4067 if (FLAG_use_range) Run<HRangeAnalysisPhase>(); 4051 Run<HRangeAnalysisPhase>();
4068 4052
4069 Run<HComputeChangeUndefinedToNaN>(); 4053 Run<HComputeChangeUndefinedToNaN>();
4070 Run<HComputeMinusZeroChecksPhase>();
4071 4054
4072 // Eliminate redundant stack checks on backwards branches. 4055 // Eliminate redundant stack checks on backwards branches.
4073 Run<HStackCheckEliminationPhase>(); 4056 Run<HStackCheckEliminationPhase>();
4074 4057
4075 if (FLAG_array_bounds_checks_elimination) Run<HBoundsCheckEliminationPhase>(); 4058 if (FLAG_array_bounds_checks_elimination) Run<HBoundsCheckEliminationPhase>();
4076 if (FLAG_array_bounds_checks_hoisting) Run<HBoundsCheckHoistingPhase>(); 4059 if (FLAG_array_bounds_checks_hoisting) Run<HBoundsCheckHoistingPhase>();
4077 if (FLAG_array_index_dehoisting) Run<HDehoistIndexComputationsPhase>(); 4060 if (FLAG_array_index_dehoisting) Run<HDehoistIndexComputationsPhase>();
4078 if (FLAG_dead_code_elimination) Run<HDeadCodeEliminationPhase>(); 4061 if (FLAG_dead_code_elimination) Run<HDeadCodeEliminationPhase>();
4079 4062
4080 RestoreActualValues(); 4063 RestoreActualValues();
(...skipping 1513 matching lines...) Expand 10 before | Expand all | Expand 10 after
5594 builder_, access_type_, ToType(types->at(i)), name_); 5577 builder_, access_type_, ToType(types->at(i)), name_);
5595 if (!test_info.IsCompatible(this)) return false; 5578 if (!test_info.IsCompatible(this)) return false;
5596 } 5579 }
5597 5580
5598 return true; 5581 return true;
5599 } 5582 }
5600 5583
5601 5584
5602 static bool NeedsWrappingFor(Type* type, Handle<JSFunction> target) { 5585 static bool NeedsWrappingFor(Type* type, Handle<JSFunction> target) {
5603 return type->Is(Type::NumberOrString()) && 5586 return type->Is(Type::NumberOrString()) &&
5604 target->shared()->is_classic_mode() && 5587 target->shared()->strict_mode() == SLOPPY &&
5605 !target->shared()->native(); 5588 !target->shared()->native();
5606 } 5589 }
5607 5590
5608 5591
5609 HInstruction* HOptimizedGraphBuilder::BuildMonomorphicAccess( 5592 HInstruction* HOptimizedGraphBuilder::BuildMonomorphicAccess(
5610 PropertyAccessInfo* info, 5593 PropertyAccessInfo* info,
5611 HValue* object, 5594 HValue* object,
5612 HValue* checked_object, 5595 HValue* checked_object,
5613 HValue* value, 5596 HValue* value,
5614 BailoutId ast_id, 5597 BailoutId ast_id,
(...skipping 320 matching lines...) Expand 10 before | Expand all | Expand 10 after
5935 Add<HStoreGlobalCell>(value, cell, lookup.GetPropertyDetails()); 5918 Add<HStoreGlobalCell>(value, cell, lookup.GetPropertyDetails());
5936 if (instr->HasObservableSideEffects()) { 5919 if (instr->HasObservableSideEffects()) {
5937 Add<HSimulate>(ast_id, REMOVABLE_SIMULATE); 5920 Add<HSimulate>(ast_id, REMOVABLE_SIMULATE);
5938 } 5921 }
5939 } else { 5922 } else {
5940 HValue* global_object = Add<HLoadNamedField>( 5923 HValue* global_object = Add<HLoadNamedField>(
5941 context(), static_cast<HValue*>(NULL), 5924 context(), static_cast<HValue*>(NULL),
5942 HObjectAccess::ForContextSlot(Context::GLOBAL_OBJECT_INDEX)); 5925 HObjectAccess::ForContextSlot(Context::GLOBAL_OBJECT_INDEX));
5943 HStoreNamedGeneric* instr = 5926 HStoreNamedGeneric* instr =
5944 Add<HStoreNamedGeneric>(global_object, var->name(), 5927 Add<HStoreNamedGeneric>(global_object, var->name(),
5945 value, function_strict_mode_flag()); 5928 value, function_strict_mode());
5946 USE(instr); 5929 USE(instr);
5947 ASSERT(instr->HasObservableSideEffects()); 5930 ASSERT(instr->HasObservableSideEffects());
5948 Add<HSimulate>(ast_id, REMOVABLE_SIMULATE); 5931 Add<HSimulate>(ast_id, REMOVABLE_SIMULATE);
5949 } 5932 }
5950 } 5933 }
5951 5934
5952 5935
5953 void HOptimizedGraphBuilder::HandleCompoundAssignment(Assignment* expr) { 5936 void HOptimizedGraphBuilder::HandleCompoundAssignment(Assignment* expr) {
5954 Expression* target = expr->target(); 5937 Expression* target = expr->target();
5955 VariableProxy* proxy = target->AsVariableProxy(); 5938 VariableProxy* proxy = target->AsVariableProxy();
(...skipping 14 matching lines...) Expand all
5970 5953
5971 switch (var->location()) { 5954 switch (var->location()) {
5972 case Variable::UNALLOCATED: 5955 case Variable::UNALLOCATED:
5973 HandleGlobalVariableAssignment(var, 5956 HandleGlobalVariableAssignment(var,
5974 Top(), 5957 Top(),
5975 expr->AssignmentId()); 5958 expr->AssignmentId());
5976 break; 5959 break;
5977 5960
5978 case Variable::PARAMETER: 5961 case Variable::PARAMETER:
5979 case Variable::LOCAL: 5962 case Variable::LOCAL:
5980 if (var->mode() == CONST) { 5963 if (var->mode() == CONST_LEGACY) {
5981 return Bailout(kUnsupportedConstCompoundAssignment); 5964 return Bailout(kUnsupportedConstCompoundAssignment);
5982 } 5965 }
5983 BindIfLive(var, Top()); 5966 BindIfLive(var, Top());
5984 break; 5967 break;
5985 5968
5986 case Variable::CONTEXT: { 5969 case Variable::CONTEXT: {
5987 // Bail out if we try to mutate a parameter value in a function 5970 // Bail out if we try to mutate a parameter value in a function
5988 // using the arguments object. We do not (yet) correctly handle the 5971 // using the arguments object. We do not (yet) correctly handle the
5989 // arguments property of the function. 5972 // arguments property of the function.
5990 if (current_info()->scope()->arguments() != NULL) { 5973 if (current_info()->scope()->arguments() != NULL) {
5991 // Parameters will be allocated to context slots. We have no 5974 // Parameters will be allocated to context slots. We have no
5992 // direct way to detect that the variable is a parameter so we do 5975 // direct way to detect that the variable is a parameter so we do
5993 // a linear search of the parameter variables. 5976 // a linear search of the parameter variables.
5994 int count = current_info()->scope()->num_parameters(); 5977 int count = current_info()->scope()->num_parameters();
5995 for (int i = 0; i < count; ++i) { 5978 for (int i = 0; i < count; ++i) {
5996 if (var == current_info()->scope()->parameter(i)) { 5979 if (var == current_info()->scope()->parameter(i)) {
5997 Bailout(kAssignmentToParameterFunctionUsesArgumentsObject); 5980 Bailout(kAssignmentToParameterFunctionUsesArgumentsObject);
5998 } 5981 }
5999 } 5982 }
6000 } 5983 }
6001 5984
6002 HStoreContextSlot::Mode mode; 5985 HStoreContextSlot::Mode mode;
6003 5986
6004 switch (var->mode()) { 5987 switch (var->mode()) {
6005 case LET: 5988 case LET:
6006 mode = HStoreContextSlot::kCheckDeoptimize; 5989 mode = HStoreContextSlot::kCheckDeoptimize;
6007 break; 5990 break;
6008 case CONST: 5991 case CONST:
6009 return ast_context()->ReturnValue(Pop());
6010 case CONST_HARMONY:
6011 // This case is checked statically so no need to 5992 // This case is checked statically so no need to
6012 // perform checks here 5993 // perform checks here
6013 UNREACHABLE(); 5994 UNREACHABLE();
5995 case CONST_LEGACY:
5996 return ast_context()->ReturnValue(Pop());
6014 default: 5997 default:
6015 mode = HStoreContextSlot::kNoCheck; 5998 mode = HStoreContextSlot::kNoCheck;
6016 } 5999 }
6017 6000
6018 HValue* context = BuildContextChainWalk(var); 6001 HValue* context = BuildContextChainWalk(var);
6019 HStoreContextSlot* instr = Add<HStoreContextSlot>( 6002 HStoreContextSlot* instr = Add<HStoreContextSlot>(
6020 context, var->index(), mode, Top()); 6003 context, var->index(), mode, Top());
6021 if (instr->HasObservableSideEffects()) { 6004 if (instr->HasObservableSideEffects()) {
6022 Add<HSimulate>(expr->AssignmentId(), REMOVABLE_SIMULATE); 6005 Add<HSimulate>(expr->AssignmentId(), REMOVABLE_SIMULATE);
6023 } 6006 }
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after
6068 return; 6051 return;
6069 } 6052 }
6070 6053
6071 if (prop != NULL) { 6054 if (prop != NULL) {
6072 HandlePropertyAssignment(expr); 6055 HandlePropertyAssignment(expr);
6073 } else if (proxy != NULL) { 6056 } else if (proxy != NULL) {
6074 Variable* var = proxy->var(); 6057 Variable* var = proxy->var();
6075 6058
6076 if (var->mode() == CONST) { 6059 if (var->mode() == CONST) {
6077 if (expr->op() != Token::INIT_CONST) { 6060 if (expr->op() != Token::INIT_CONST) {
6061 return Bailout(kNonInitializerAssignmentToConst);
6062 }
6063 } else if (var->mode() == CONST_LEGACY) {
6064 if (expr->op() != Token::INIT_CONST_LEGACY) {
6078 CHECK_ALIVE(VisitForValue(expr->value())); 6065 CHECK_ALIVE(VisitForValue(expr->value()));
6079 return ast_context()->ReturnValue(Pop()); 6066 return ast_context()->ReturnValue(Pop());
6080 } 6067 }
6081 6068
6082 if (var->IsStackAllocated()) { 6069 if (var->IsStackAllocated()) {
6083 // We insert a use of the old value to detect unsupported uses of const 6070 // We insert a use of the old value to detect unsupported uses of const
6084 // variables (e.g. initialization inside a loop). 6071 // variables (e.g. initialization inside a loop).
6085 HValue* old_value = environment()->Lookup(var); 6072 HValue* old_value = environment()->Lookup(var);
6086 Add<HUseConst>(old_value); 6073 Add<HUseConst>(old_value);
6087 } 6074 }
6088 } else if (var->mode() == CONST_HARMONY) {
6089 if (expr->op() != Token::INIT_CONST_HARMONY) {
6090 return Bailout(kNonInitializerAssignmentToConst);
6091 }
6092 } 6075 }
6093 6076
6094 if (proxy->IsArguments()) return Bailout(kAssignmentToArguments); 6077 if (proxy->IsArguments()) return Bailout(kAssignmentToArguments);
6095 6078
6096 // Handle the assignment. 6079 // Handle the assignment.
6097 switch (var->location()) { 6080 switch (var->location()) {
6098 case Variable::UNALLOCATED: 6081 case Variable::UNALLOCATED:
6099 CHECK_ALIVE(VisitForValue(expr->value())); 6082 CHECK_ALIVE(VisitForValue(expr->value()));
6100 HandleGlobalVariableAssignment(var, 6083 HandleGlobalVariableAssignment(var,
6101 Top(), 6084 Top(),
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after
6137 } 6120 }
6138 6121
6139 CHECK_ALIVE(VisitForValue(expr->value())); 6122 CHECK_ALIVE(VisitForValue(expr->value()));
6140 HStoreContextSlot::Mode mode; 6123 HStoreContextSlot::Mode mode;
6141 if (expr->op() == Token::ASSIGN) { 6124 if (expr->op() == Token::ASSIGN) {
6142 switch (var->mode()) { 6125 switch (var->mode()) {
6143 case LET: 6126 case LET:
6144 mode = HStoreContextSlot::kCheckDeoptimize; 6127 mode = HStoreContextSlot::kCheckDeoptimize;
6145 break; 6128 break;
6146 case CONST: 6129 case CONST:
6147 return ast_context()->ReturnValue(Pop());
6148 case CONST_HARMONY:
6149 // This case is checked statically so no need to 6130 // This case is checked statically so no need to
6150 // perform checks here 6131 // perform checks here
6151 UNREACHABLE(); 6132 UNREACHABLE();
6133 case CONST_LEGACY:
6134 return ast_context()->ReturnValue(Pop());
6152 default: 6135 default:
6153 mode = HStoreContextSlot::kNoCheck; 6136 mode = HStoreContextSlot::kNoCheck;
6154 } 6137 }
6155 } else if (expr->op() == Token::INIT_VAR || 6138 } else if (expr->op() == Token::INIT_VAR ||
6156 expr->op() == Token::INIT_LET || 6139 expr->op() == Token::INIT_LET ||
6157 expr->op() == Token::INIT_CONST_HARMONY) { 6140 expr->op() == Token::INIT_CONST) {
6158 mode = HStoreContextSlot::kNoCheck; 6141 mode = HStoreContextSlot::kNoCheck;
6159 } else { 6142 } else {
6160 ASSERT(expr->op() == Token::INIT_CONST); 6143 ASSERT(expr->op() == Token::INIT_CONST_LEGACY);
6161 6144
6162 mode = HStoreContextSlot::kCheckIgnoreAssignment; 6145 mode = HStoreContextSlot::kCheckIgnoreAssignment;
6163 } 6146 }
6164 6147
6165 HValue* context = BuildContextChainWalk(var); 6148 HValue* context = BuildContextChainWalk(var);
6166 HStoreContextSlot* instr = Add<HStoreContextSlot>( 6149 HStoreContextSlot* instr = Add<HStoreContextSlot>(
6167 context, var->index(), mode, Top()); 6150 context, var->index(), mode, Top());
6168 if (instr->HasObservableSideEffects()) { 6151 if (instr->HasObservableSideEffects()) {
6169 Add<HSimulate>(expr->AssignmentId(), REMOVABLE_SIMULATE); 6152 Add<HSimulate>(expr->AssignmentId(), REMOVABLE_SIMULATE);
6170 } 6153 }
(...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after
6244 Handle<String> name, 6227 Handle<String> name,
6245 HValue* value, 6228 HValue* value,
6246 bool is_uninitialized) { 6229 bool is_uninitialized) {
6247 if (is_uninitialized) { 6230 if (is_uninitialized) {
6248 Add<HDeoptimize>("Insufficient type feedback for generic named access", 6231 Add<HDeoptimize>("Insufficient type feedback for generic named access",
6249 Deoptimizer::SOFT); 6232 Deoptimizer::SOFT);
6250 } 6233 }
6251 if (access_type == LOAD) { 6234 if (access_type == LOAD) {
6252 return New<HLoadNamedGeneric>(object, name); 6235 return New<HLoadNamedGeneric>(object, name);
6253 } else { 6236 } else {
6254 return New<HStoreNamedGeneric>( 6237 return New<HStoreNamedGeneric>(object, name, value, function_strict_mode());
6255 object, name, value, function_strict_mode_flag());
6256 } 6238 }
6257 } 6239 }
6258 6240
6259 6241
6260 6242
6261 HInstruction* HOptimizedGraphBuilder::BuildKeyedGeneric( 6243 HInstruction* HOptimizedGraphBuilder::BuildKeyedGeneric(
6262 PropertyAccessType access_type, 6244 PropertyAccessType access_type,
6263 HValue* object, 6245 HValue* object,
6264 HValue* key, 6246 HValue* key,
6265 HValue* value) { 6247 HValue* value) {
6266 if (access_type == LOAD) { 6248 if (access_type == LOAD) {
6267 return New<HLoadKeyedGeneric>(object, key); 6249 return New<HLoadKeyedGeneric>(object, key);
6268 } else { 6250 } else {
6269 return New<HStoreKeyedGeneric>( 6251 return New<HStoreKeyedGeneric>(object, key, value, function_strict_mode());
6270 object, key, value, function_strict_mode_flag());
6271 } 6252 }
6272 } 6253 }
6273 6254
6274 6255
6275 LoadKeyedHoleMode HOptimizedGraphBuilder::BuildKeyedHoleMode(Handle<Map> map) { 6256 LoadKeyedHoleMode HOptimizedGraphBuilder::BuildKeyedHoleMode(Handle<Map> map) {
6276 // Loads from a "stock" fast holey double arrays can elide the hole check. 6257 // Loads from a "stock" fast holey double arrays can elide the hole check.
6277 LoadKeyedHoleMode load_mode = NEVER_RETURN_HOLE; 6258 LoadKeyedHoleMode load_mode = NEVER_RETURN_HOLE;
6278 if (*map == isolate()->get_initial_js_array_map(FAST_HOLEY_DOUBLE_ELEMENTS) && 6259 if (*map == isolate()->get_initial_js_array_map(FAST_HOLEY_DOUBLE_ELEMENTS) &&
6279 isolate()->IsFastArrayConstructorPrototypeChainIntact()) { 6260 isolate()->IsFastArrayConstructorPrototypeChainIntact()) {
6280 Handle<JSObject> prototype(JSObject::cast(map->prototype()), isolate()); 6261 Handle<JSObject> prototype(JSObject::cast(map->prototype()), isolate());
(...skipping 937 matching lines...) Expand 10 before | Expand all | Expand 10 after
7218 return false; 7199 return false;
7219 } 7200 }
7220 if (target_shared->scope_info() == ScopeInfo::Empty(isolate())) { 7201 if (target_shared->scope_info() == ScopeInfo::Empty(isolate())) {
7221 // The scope info might not have been set if a lazily compiled 7202 // The scope info might not have been set if a lazily compiled
7222 // function is inlined before being called for the first time. 7203 // function is inlined before being called for the first time.
7223 Handle<ScopeInfo> target_scope_info = 7204 Handle<ScopeInfo> target_scope_info =
7224 ScopeInfo::Create(target_info.scope(), zone()); 7205 ScopeInfo::Create(target_info.scope(), zone());
7225 target_shared->set_scope_info(*target_scope_info); 7206 target_shared->set_scope_info(*target_scope_info);
7226 } 7207 }
7227 target_shared->EnableDeoptimizationSupport(*target_info.code()); 7208 target_shared->EnableDeoptimizationSupport(*target_info.code());
7209 target_shared->set_feedback_vector(*target_info.feedback_vector());
7228 Compiler::RecordFunctionCompilation(Logger::FUNCTION_TAG, 7210 Compiler::RecordFunctionCompilation(Logger::FUNCTION_TAG,
7229 &target_info, 7211 &target_info,
7230 target_shared); 7212 target_shared);
7231 } 7213 }
7232 7214
7233 // ---------------------------------------------------------------- 7215 // ----------------------------------------------------------------
7234 // After this point, we've made a decision to inline this function (so 7216 // After this point, we've made a decision to inline this function (so
7235 // TryInline should always return true). 7217 // TryInline should always return true).
7236 7218
7237 // Type-check the inlined function. 7219 // Type-check the inlined function.
(...skipping 708 matching lines...) Expand 10 before | Expand all | Expand 10 after
7946 Drop(1); // Function. 7928 Drop(1); // Function.
7947 ast_context()->ReturnInstruction(call, expr->id()); 7929 ast_context()->ReturnInstruction(call, expr->id());
7948 return true; 7930 return true;
7949 } 7931 }
7950 } 7932 }
7951 7933
7952 7934
7953 HValue* HOptimizedGraphBuilder::ImplicitReceiverFor(HValue* function, 7935 HValue* HOptimizedGraphBuilder::ImplicitReceiverFor(HValue* function,
7954 Handle<JSFunction> target) { 7936 Handle<JSFunction> target) {
7955 SharedFunctionInfo* shared = target->shared(); 7937 SharedFunctionInfo* shared = target->shared();
7956 if (shared->is_classic_mode() && !shared->native()) { 7938 if (shared->strict_mode() == SLOPPY && !shared->native()) {
7957 // Cannot embed a direct reference to the global proxy 7939 // Cannot embed a direct reference to the global proxy
7958 // as is it dropped on deserialization. 7940 // as is it dropped on deserialization.
7959 CHECK(!Serializer::enabled()); 7941 CHECK(!Serializer::enabled());
7960 Handle<JSObject> global_receiver( 7942 Handle<JSObject> global_receiver(
7961 target->context()->global_object()->global_receiver()); 7943 target->context()->global_object()->global_receiver());
7962 return Add<HConstant>(global_receiver); 7944 return Add<HConstant>(global_receiver);
7963 } 7945 }
7964 return graph()->GetConstantUndefined(); 7946 return graph()->GetConstantUndefined();
7965 } 7947 }
7966 7948
(...skipping 81 matching lines...) Expand 10 before | Expand all | Expand 10 after
8048 call = New<HCallFunction>(function, argument_count, flags); 8030 call = New<HCallFunction>(function, argument_count, flags);
8049 } 8031 }
8050 PushArgumentsFromEnvironment(argument_count); 8032 PushArgumentsFromEnvironment(argument_count);
8051 8033
8052 } else { 8034 } else {
8053 VariableProxy* proxy = expr->expression()->AsVariableProxy(); 8035 VariableProxy* proxy = expr->expression()->AsVariableProxy();
8054 if (proxy != NULL && proxy->var()->is_possibly_eval(isolate())) { 8036 if (proxy != NULL && proxy->var()->is_possibly_eval(isolate())) {
8055 return Bailout(kPossibleDirectCallToEval); 8037 return Bailout(kPossibleDirectCallToEval);
8056 } 8038 }
8057 8039
8040 // The function is on the stack in the unoptimized code during
8041 // evaluation of the arguments.
8042 CHECK_ALIVE(VisitForValue(expr->expression()));
8043 HValue* function = Top();
8058 bool global_call = proxy != NULL && proxy->var()->IsUnallocated(); 8044 bool global_call = proxy != NULL && proxy->var()->IsUnallocated();
8059 if (global_call) { 8045 if (global_call) {
8060 Variable* var = proxy->var(); 8046 Variable* var = proxy->var();
8061 bool known_global_function = false; 8047 bool known_global_function = false;
8062 // If there is a global property cell for the name at compile time and 8048 // If there is a global property cell for the name at compile time and
8063 // access check is not enabled we assume that the function will not change 8049 // access check is not enabled we assume that the function will not change
8064 // and generate optimized code for calling the function. 8050 // and generate optimized code for calling the function.
8065 LookupResult lookup(isolate()); 8051 LookupResult lookup(isolate());
8066 GlobalPropertyAccess type = LookupGlobalProperty(var, &lookup, LOAD); 8052 GlobalPropertyAccess type = LookupGlobalProperty(var, &lookup, LOAD);
8067 if (type == kUseCell && 8053 if (type == kUseCell &&
8068 !current_info()->global_object()->IsAccessCheckNeeded()) { 8054 !current_info()->global_object()->IsAccessCheckNeeded()) {
8069 Handle<GlobalObject> global(current_info()->global_object()); 8055 Handle<GlobalObject> global(current_info()->global_object());
8070 known_global_function = expr->ComputeGlobalTarget(global, &lookup); 8056 known_global_function = expr->ComputeGlobalTarget(global, &lookup);
8071 } 8057 }
8072 CHECK_ALIVE(VisitForValue(expr->expression()));
8073 HValue* function = Top();
8074 if (known_global_function) { 8058 if (known_global_function) {
8075 Add<HCheckValue>(function, expr->target()); 8059 Add<HCheckValue>(function, expr->target());
8076 8060
8077 // Placeholder for the receiver. 8061 // Placeholder for the receiver.
8078 Push(graph()->GetConstantUndefined()); 8062 Push(graph()->GetConstantUndefined());
8079 CHECK_ALIVE(VisitExpressions(expr->arguments())); 8063 CHECK_ALIVE(VisitExpressions(expr->arguments()));
8080 8064
8081 // Patch the global object on the stack by the expected receiver. 8065 // Patch the global object on the stack by the expected receiver.
8082 HValue* receiver = ImplicitReceiverFor(function, expr->target()); 8066 HValue* receiver = ImplicitReceiverFor(function, expr->target());
8083 const int receiver_index = argument_count - 1; 8067 const int receiver_index = argument_count - 1;
8084 environment()->SetExpressionStackAt(receiver_index, receiver); 8068 environment()->SetExpressionStackAt(receiver_index, receiver);
8085 8069
8086 if (TryInlineBuiltinFunctionCall(expr)) { 8070 if (TryInlineBuiltinFunctionCall(expr)) {
8087 if (FLAG_trace_inlining) { 8071 if (FLAG_trace_inlining) {
8088 PrintF("Inlining builtin "); 8072 PrintF("Inlining builtin ");
8089 expr->target()->ShortPrint(); 8073 expr->target()->ShortPrint();
8090 PrintF("\n"); 8074 PrintF("\n");
8091 } 8075 }
8092 return; 8076 return;
8093 } 8077 }
8094 if (TryInlineApiFunctionCall(expr, receiver)) return; 8078 if (TryInlineApiFunctionCall(expr, receiver)) return;
8095 if (TryInlineCall(expr)) return; 8079 if (TryInlineCall(expr)) return;
8096 8080
8097 PushArgumentsFromEnvironment(argument_count); 8081 PushArgumentsFromEnvironment(argument_count);
8098 call = BuildCallConstantFunction(expr->target(), argument_count); 8082 call = BuildCallConstantFunction(expr->target(), argument_count);
8099 } else { 8083 } else {
8100 Push(Add<HPushArgument>(graph()->GetConstantUndefined())); 8084 Push(graph()->GetConstantUndefined());
8101 CHECK_ALIVE(VisitArgumentList(expr->arguments())); 8085 CHECK_ALIVE(VisitExpressions(expr->arguments()));
8086 PushArgumentsFromEnvironment(argument_count);
8102 call = New<HCallFunction>(function, argument_count); 8087 call = New<HCallFunction>(function, argument_count);
8103 Drop(argument_count);
8104 } 8088 }
8105 8089
8106 } else if (expr->IsMonomorphic()) { 8090 } else if (expr->IsMonomorphic()) {
8107 // The function is on the stack in the unoptimized code during
8108 // evaluation of the arguments.
8109 CHECK_ALIVE(VisitForValue(expr->expression()));
8110 HValue* function = Top();
8111
8112 Add<HCheckValue>(function, expr->target()); 8091 Add<HCheckValue>(function, expr->target());
8113 8092
8114 Push(graph()->GetConstantUndefined()); 8093 Push(graph()->GetConstantUndefined());
8115 CHECK_ALIVE(VisitExpressions(expr->arguments())); 8094 CHECK_ALIVE(VisitExpressions(expr->arguments()));
8116 8095
8117 HValue* receiver = ImplicitReceiverFor(function, expr->target()); 8096 HValue* receiver = ImplicitReceiverFor(function, expr->target());
8118 const int receiver_index = argument_count - 1; 8097 const int receiver_index = argument_count - 1;
8119 environment()->SetExpressionStackAt(receiver_index, receiver); 8098 environment()->SetExpressionStackAt(receiver_index, receiver);
8120 8099
8121 if (TryInlineBuiltinFunctionCall(expr)) { 8100 if (TryInlineBuiltinFunctionCall(expr)) {
8122 if (FLAG_trace_inlining) { 8101 if (FLAG_trace_inlining) {
8123 PrintF("Inlining builtin "); 8102 PrintF("Inlining builtin ");
8124 expr->target()->ShortPrint(); 8103 expr->target()->ShortPrint();
8125 PrintF("\n"); 8104 PrintF("\n");
8126 } 8105 }
8127 return; 8106 return;
8128 } 8107 }
8129 if (TryInlineApiFunctionCall(expr, receiver)) return; 8108 if (TryInlineApiFunctionCall(expr, receiver)) return;
8130 8109
8131 if (TryInlineCall(expr)) return; 8110 if (TryInlineCall(expr)) return;
8132 8111
8133 call = PreProcessCall(New<HInvokeFunction>( 8112 call = PreProcessCall(New<HInvokeFunction>(
8134 function, expr->target(), argument_count)); 8113 function, expr->target(), argument_count));
8135 8114
8136 } else { 8115 } else {
8137 CHECK_ALIVE(VisitForValue(expr->expression())); 8116 Push(graph()->GetConstantUndefined());
8138 HValue* function = Top(); 8117 CHECK_ALIVE(VisitExpressions(expr->arguments()));
8139 HValue* receiver = graph()->GetConstantUndefined(); 8118 PushArgumentsFromEnvironment(argument_count);
8140 Push(Add<HPushArgument>(receiver));
8141 CHECK_ALIVE(VisitArgumentList(expr->arguments()));
8142 call = New<HCallFunction>(function, argument_count); 8119 call = New<HCallFunction>(function, argument_count);
8143 Drop(argument_count);
8144 } 8120 }
8145 } 8121 }
8146 8122
8147 Drop(1); // Drop the function. 8123 Drop(1); // Drop the function.
8148 return ast_context()->ReturnInstruction(call, expr->id()); 8124 return ast_context()->ReturnInstruction(call, expr->id());
8149 } 8125 }
8150 8126
8151 8127
8152 void HOptimizedGraphBuilder::BuildInlinedCallNewArray(CallNew* expr) { 8128 void HOptimizedGraphBuilder::BuildInlinedCallNewArray(CallNew* expr) {
8153 NoObservableSideEffectsScope no_effects(this); 8129 NoObservableSideEffectsScope no_effects(this);
(...skipping 247 matching lines...) Expand 10 before | Expand all | Expand 10 after
8401 8377
8402 // Lookup table for generators for runtime calls that are generated inline. 8378 // Lookup table for generators for runtime calls that are generated inline.
8403 // Elements of the table are member pointers to functions of 8379 // Elements of the table are member pointers to functions of
8404 // HOptimizedGraphBuilder. 8380 // HOptimizedGraphBuilder.
8405 #define INLINE_FUNCTION_GENERATOR_ADDRESS(Name, argc, ressize) \ 8381 #define INLINE_FUNCTION_GENERATOR_ADDRESS(Name, argc, ressize) \
8406 &HOptimizedGraphBuilder::Generate##Name, 8382 &HOptimizedGraphBuilder::Generate##Name,
8407 8383
8408 const HOptimizedGraphBuilder::InlineFunctionGenerator 8384 const HOptimizedGraphBuilder::InlineFunctionGenerator
8409 HOptimizedGraphBuilder::kInlineFunctionGenerators[] = { 8385 HOptimizedGraphBuilder::kInlineFunctionGenerators[] = {
8410 INLINE_FUNCTION_LIST(INLINE_FUNCTION_GENERATOR_ADDRESS) 8386 INLINE_FUNCTION_LIST(INLINE_FUNCTION_GENERATOR_ADDRESS)
8411 INLINE_RUNTIME_FUNCTION_LIST(INLINE_FUNCTION_GENERATOR_ADDRESS)
8412 }; 8387 };
8413 #undef INLINE_FUNCTION_GENERATOR_ADDRESS 8388 #undef INLINE_FUNCTION_GENERATOR_ADDRESS
8414 8389
8415 8390
8416 template <class ViewClass> 8391 template <class ViewClass>
8417 void HGraphBuilder::BuildArrayBufferViewInitialization( 8392 void HGraphBuilder::BuildArrayBufferViewInitialization(
8418 HValue* obj, 8393 HValue* obj,
8419 HValue* buffer, 8394 HValue* buffer,
8420 HValue* byte_offset, 8395 HValue* byte_offset,
8421 HValue* byte_length) { 8396 HValue* byte_length) {
(...skipping 151 matching lines...) Expand 10 before | Expand all | Expand 10 after
8573 Add<HStoreNamedField>(elements, 8548 Add<HStoreNamedField>(elements,
8574 HObjectAccess::ForFixedArrayLength(), 8549 HObjectAccess::ForFixedArrayLength(),
8575 length); 8550 length);
8576 Add<HStoreNamedField>( 8551 Add<HStoreNamedField>(
8577 obj, HObjectAccess::ForElementsPointer(), elements); 8552 obj, HObjectAccess::ForElementsPointer(), elements);
8578 } 8553 }
8579 8554
8580 if (!is_zero_byte_offset) { 8555 if (!is_zero_byte_offset) {
8581 byte_offset_smi.Else(); 8556 byte_offset_smi.Else();
8582 { // byte_offset is not Smi. 8557 { // byte_offset is not Smi.
8583 Push(Add<HPushArgument>(obj)); 8558 Push(obj);
8584 VisitArgument(arguments->at(kArrayIdArg)); 8559 CHECK_ALIVE(VisitForValue(arguments->at(kArrayIdArg)));
8585 Push(Add<HPushArgument>(buffer)); 8560 Push(buffer);
8586 Push(Add<HPushArgument>(byte_offset)); 8561 Push(byte_offset);
8587 Push(Add<HPushArgument>(byte_length)); 8562 Push(byte_length);
8563 PushArgumentsFromEnvironment(kArgsLength);
8588 Add<HCallRuntime>(expr->name(), expr->function(), kArgsLength); 8564 Add<HCallRuntime>(expr->name(), expr->function(), kArgsLength);
8589 Drop(kArgsLength);
8590 } 8565 }
8591 } 8566 }
8592 byte_offset_smi.End(); 8567 byte_offset_smi.End();
8593 } 8568 }
8594 8569
8595 8570
8596 void HOptimizedGraphBuilder::VisitCallRuntime(CallRuntime* expr) { 8571 void HOptimizedGraphBuilder::VisitCallRuntime(CallRuntime* expr) {
8597 ASSERT(!HasStackOverflow()); 8572 ASSERT(!HasStackOverflow());
8598 ASSERT(current_block() != NULL); 8573 ASSERT(current_block() != NULL);
8599 ASSERT(current_block()->HasPredecessor()); 8574 ASSERT(current_block()->HasPredecessor());
(...skipping 26 matching lines...) Expand all
8626 static_cast<int>(Runtime::kFirstInlineFunction); 8601 static_cast<int>(Runtime::kFirstInlineFunction);
8627 ASSERT(lookup_index >= 0); 8602 ASSERT(lookup_index >= 0);
8628 ASSERT(static_cast<size_t>(lookup_index) < 8603 ASSERT(static_cast<size_t>(lookup_index) <
8629 ARRAY_SIZE(kInlineFunctionGenerators)); 8604 ARRAY_SIZE(kInlineFunctionGenerators));
8630 InlineFunctionGenerator generator = kInlineFunctionGenerators[lookup_index]; 8605 InlineFunctionGenerator generator = kInlineFunctionGenerators[lookup_index];
8631 8606
8632 // Call the inline code generator using the pointer-to-member. 8607 // Call the inline code generator using the pointer-to-member.
8633 (this->*generator)(expr); 8608 (this->*generator)(expr);
8634 } else { 8609 } else {
8635 ASSERT(function->intrinsic_type == Runtime::RUNTIME); 8610 ASSERT(function->intrinsic_type == Runtime::RUNTIME);
8636 CHECK_ALIVE(VisitArgumentList(expr->arguments()));
8637
8638 Handle<String> name = expr->name(); 8611 Handle<String> name = expr->name();
8639 int argument_count = expr->arguments()->length(); 8612 int argument_count = expr->arguments()->length();
8613 CHECK_ALIVE(VisitExpressions(expr->arguments()));
8614 PushArgumentsFromEnvironment(argument_count);
8640 HCallRuntime* call = New<HCallRuntime>(name, function, 8615 HCallRuntime* call = New<HCallRuntime>(name, function,
8641 argument_count); 8616 argument_count);
8642 Drop(argument_count);
8643 return ast_context()->ReturnInstruction(call, expr->id()); 8617 return ast_context()->ReturnInstruction(call, expr->id());
8644 } 8618 }
8645 } 8619 }
8646 8620
8647 8621
8648 void HOptimizedGraphBuilder::VisitUnaryOperation(UnaryOperation* expr) { 8622 void HOptimizedGraphBuilder::VisitUnaryOperation(UnaryOperation* expr) {
8649 ASSERT(!HasStackOverflow()); 8623 ASSERT(!HasStackOverflow());
8650 ASSERT(current_block() != NULL); 8624 ASSERT(current_block() != NULL);
8651 ASSERT(current_block()->HasPredecessor()); 8625 ASSERT(current_block()->HasPredecessor());
8652 switch (expr->op()) { 8626 switch (expr->op()) {
(...skipping 10 matching lines...) Expand all
8663 Property* prop = expr->expression()->AsProperty(); 8637 Property* prop = expr->expression()->AsProperty();
8664 VariableProxy* proxy = expr->expression()->AsVariableProxy(); 8638 VariableProxy* proxy = expr->expression()->AsVariableProxy();
8665 if (prop != NULL) { 8639 if (prop != NULL) {
8666 CHECK_ALIVE(VisitForValue(prop->obj())); 8640 CHECK_ALIVE(VisitForValue(prop->obj()));
8667 CHECK_ALIVE(VisitForValue(prop->key())); 8641 CHECK_ALIVE(VisitForValue(prop->key()));
8668 HValue* key = Pop(); 8642 HValue* key = Pop();
8669 HValue* obj = Pop(); 8643 HValue* obj = Pop();
8670 HValue* function = AddLoadJSBuiltin(Builtins::DELETE); 8644 HValue* function = AddLoadJSBuiltin(Builtins::DELETE);
8671 Add<HPushArgument>(obj); 8645 Add<HPushArgument>(obj);
8672 Add<HPushArgument>(key); 8646 Add<HPushArgument>(key);
8673 Add<HPushArgument>(Add<HConstant>(function_strict_mode_flag())); 8647 Add<HPushArgument>(Add<HConstant>(function_strict_mode()));
8674 // TODO(olivf) InvokeFunction produces a check for the parameter count, 8648 // TODO(olivf) InvokeFunction produces a check for the parameter count,
8675 // even though we are certain to pass the correct number of arguments here. 8649 // even though we are certain to pass the correct number of arguments here.
8676 HInstruction* instr = New<HInvokeFunction>(function, 3); 8650 HInstruction* instr = New<HInvokeFunction>(function, 3);
8677 return ast_context()->ReturnInstruction(instr, expr->id()); 8651 return ast_context()->ReturnInstruction(instr, expr->id());
8678 } else if (proxy != NULL) { 8652 } else if (proxy != NULL) {
8679 Variable* var = proxy->var(); 8653 Variable* var = proxy->var();
8680 if (var->IsUnallocated()) { 8654 if (var->IsUnallocated()) {
8681 Bailout(kDeleteWithGlobalVariable); 8655 Bailout(kDeleteWithGlobalVariable);
8682 } else if (var->IsStackAllocated() || var->IsContextSlot()) { 8656 } else if (var->IsStackAllocated() || var->IsContextSlot()) {
8683 // Result of deleting non-global variables is false. 'this' is not 8657 // Result of deleting non-global variables is false. 'this' is not
(...skipping 143 matching lines...) Expand 10 before | Expand all | Expand 10 after
8827 // Match the full code generator stack by simulating an extra stack 8801 // Match the full code generator stack by simulating an extra stack
8828 // element for postfix operations in a non-effect context. The return 8802 // element for postfix operations in a non-effect context. The return
8829 // value is ToNumber(input). 8803 // value is ToNumber(input).
8830 bool returns_original_input = 8804 bool returns_original_input =
8831 expr->is_postfix() && !ast_context()->IsEffect(); 8805 expr->is_postfix() && !ast_context()->IsEffect();
8832 HValue* input = NULL; // ToNumber(original_input). 8806 HValue* input = NULL; // ToNumber(original_input).
8833 HValue* after = NULL; // The result after incrementing or decrementing. 8807 HValue* after = NULL; // The result after incrementing or decrementing.
8834 8808
8835 if (proxy != NULL) { 8809 if (proxy != NULL) {
8836 Variable* var = proxy->var(); 8810 Variable* var = proxy->var();
8837 if (var->mode() == CONST) { 8811 if (var->mode() == CONST_LEGACY) {
8838 return Bailout(kUnsupportedCountOperationWithConst); 8812 return Bailout(kUnsupportedCountOperationWithConst);
8839 } 8813 }
8840 // Argument of the count operation is a variable, not a property. 8814 // Argument of the count operation is a variable, not a property.
8841 ASSERT(prop == NULL); 8815 ASSERT(prop == NULL);
8842 CHECK_ALIVE(VisitForValue(target)); 8816 CHECK_ALIVE(VisitForValue(target));
8843 8817
8844 after = BuildIncrement(returns_original_input, expr); 8818 after = BuildIncrement(returns_original_input, expr);
8845 input = returns_original_input ? Top() : Pop(); 8819 input = returns_original_input ? Top() : Pop();
8846 Push(after); 8820 Push(after);
8847 8821
(...skipping 103 matching lines...) Expand 10 before | Expand all | Expand 10 after
8951 static bool ShiftAmountsAllowReplaceByRotate(HValue* sa, 8925 static bool ShiftAmountsAllowReplaceByRotate(HValue* sa,
8952 HValue* const32_minus_sa) { 8926 HValue* const32_minus_sa) {
8953 if (sa->IsConstant() && const32_minus_sa->IsConstant()) { 8927 if (sa->IsConstant() && const32_minus_sa->IsConstant()) {
8954 const HConstant* c1 = HConstant::cast(sa); 8928 const HConstant* c1 = HConstant::cast(sa);
8955 const HConstant* c2 = HConstant::cast(const32_minus_sa); 8929 const HConstant* c2 = HConstant::cast(const32_minus_sa);
8956 return c1->HasInteger32Value() && c2->HasInteger32Value() && 8930 return c1->HasInteger32Value() && c2->HasInteger32Value() &&
8957 (c1->Integer32Value() + c2->Integer32Value() == 32); 8931 (c1->Integer32Value() + c2->Integer32Value() == 32);
8958 } 8932 }
8959 if (!const32_minus_sa->IsSub()) return false; 8933 if (!const32_minus_sa->IsSub()) return false;
8960 HSub* sub = HSub::cast(const32_minus_sa); 8934 HSub* sub = HSub::cast(const32_minus_sa);
8961 if (sa != sub->right()) return false; 8935 return sub->left()->EqualsInteger32Constant(32) && sub->right() == sa;
8962 HValue* const32 = sub->left();
8963 if (!const32->IsConstant() ||
8964 HConstant::cast(const32)->Integer32Value() != 32) {
8965 return false;
8966 }
8967 return (sub->right() == sa);
8968 } 8936 }
8969 8937
8970 8938
8971 // Checks if the left and the right are shift instructions with the oposite 8939 // Checks if the left and the right are shift instructions with the oposite
8972 // directions that can be replaced by one rotate right instruction or not. 8940 // directions that can be replaced by one rotate right instruction or not.
8973 // Returns the operand and the shift amount for the rotate instruction in the 8941 // Returns the operand and the shift amount for the rotate instruction in the
8974 // former case. 8942 // former case.
8975 bool HGraphBuilder::MatchRotateRight(HValue* left, 8943 bool HGraphBuilder::MatchRotateRight(HValue* left,
8976 HValue* right, 8944 HValue* right,
8977 HValue** operand, 8945 HValue** operand,
(...skipping 266 matching lines...) Expand 10 before | Expand all | Expand 10 after
9244 case Token::ADD: 9212 case Token::ADD:
9245 instr = AddUncasted<HAdd>(left, right); 9213 instr = AddUncasted<HAdd>(left, right);
9246 break; 9214 break;
9247 case Token::SUB: 9215 case Token::SUB:
9248 instr = AddUncasted<HSub>(left, right); 9216 instr = AddUncasted<HSub>(left, right);
9249 break; 9217 break;
9250 case Token::MUL: 9218 case Token::MUL:
9251 instr = AddUncasted<HMul>(left, right); 9219 instr = AddUncasted<HMul>(left, right);
9252 break; 9220 break;
9253 case Token::MOD: { 9221 case Token::MOD: {
9254 if (fixed_right_arg.has_value) { 9222 if (fixed_right_arg.has_value &&
9255 if (right->IsConstant()) { 9223 !right->EqualsInteger32Constant(fixed_right_arg.value)) {
9256 HConstant* c_right = HConstant::cast(right); 9224 HConstant* fixed_right = Add<HConstant>(
9257 if (c_right->HasInteger32Value()) { 9225 static_cast<int>(fixed_right_arg.value));
9258 ASSERT_EQ(fixed_right_arg.value, c_right->Integer32Value()); 9226 IfBuilder if_same(this);
9259 } 9227 if_same.If<HCompareNumericAndBranch>(right, fixed_right, Token::EQ);
9260 } else { 9228 if_same.Then();
9261 HConstant* fixed_right = Add<HConstant>( 9229 if_same.ElseDeopt("Unexpected RHS of binary operation");
9262 static_cast<int>(fixed_right_arg.value)); 9230 right = fixed_right;
9263 IfBuilder if_same(this);
9264 if_same.If<HCompareNumericAndBranch>(right, fixed_right, Token::EQ);
9265 if_same.Then();
9266 if_same.ElseDeopt("Unexpected RHS of binary operation");
9267 right = fixed_right;
9268 }
9269 } 9231 }
9270 instr = AddUncasted<HMod>(left, right); 9232 instr = AddUncasted<HMod>(left, right);
9271 break; 9233 break;
9272 } 9234 }
9273 case Token::DIV: 9235 case Token::DIV:
9274 instr = AddUncasted<HDiv>(left, right); 9236 instr = AddUncasted<HDiv>(left, right);
9275 break; 9237 break;
9276 case Token::BIT_XOR: 9238 case Token::BIT_XOR:
9277 case Token::BIT_AND: 9239 case Token::BIT_AND:
9278 instr = AddUncasted<HBitwise>(op, left, right); 9240 instr = AddUncasted<HBitwise>(op, left, right);
(...skipping 758 matching lines...) Expand 10 before | Expand all | Expand 10 after
10037 void HOptimizedGraphBuilder::VisitDeclarations( 9999 void HOptimizedGraphBuilder::VisitDeclarations(
10038 ZoneList<Declaration*>* declarations) { 10000 ZoneList<Declaration*>* declarations) {
10039 ASSERT(globals_.is_empty()); 10001 ASSERT(globals_.is_empty());
10040 AstVisitor::VisitDeclarations(declarations); 10002 AstVisitor::VisitDeclarations(declarations);
10041 if (!globals_.is_empty()) { 10003 if (!globals_.is_empty()) {
10042 Handle<FixedArray> array = 10004 Handle<FixedArray> array =
10043 isolate()->factory()->NewFixedArray(globals_.length(), TENURED); 10005 isolate()->factory()->NewFixedArray(globals_.length(), TENURED);
10044 for (int i = 0; i < globals_.length(); ++i) array->set(i, *globals_.at(i)); 10006 for (int i = 0; i < globals_.length(); ++i) array->set(i, *globals_.at(i));
10045 int flags = DeclareGlobalsEvalFlag::encode(current_info()->is_eval()) | 10007 int flags = DeclareGlobalsEvalFlag::encode(current_info()->is_eval()) |
10046 DeclareGlobalsNativeFlag::encode(current_info()->is_native()) | 10008 DeclareGlobalsNativeFlag::encode(current_info()->is_native()) |
10047 DeclareGlobalsLanguageMode::encode(current_info()->language_mode()); 10009 DeclareGlobalsStrictMode::encode(current_info()->strict_mode());
10048 Add<HDeclareGlobals>(array, flags); 10010 Add<HDeclareGlobals>(array, flags);
10049 globals_.Clear(); 10011 globals_.Clear();
10050 } 10012 }
10051 } 10013 }
10052 10014
10053 10015
10054 void HOptimizedGraphBuilder::VisitVariableDeclaration( 10016 void HOptimizedGraphBuilder::VisitVariableDeclaration(
10055 VariableDeclaration* declaration) { 10017 VariableDeclaration* declaration) {
10056 VariableProxy* proxy = declaration->proxy(); 10018 VariableProxy* proxy = declaration->proxy();
10057 VariableMode mode = declaration->mode(); 10019 VariableMode mode = declaration->mode();
10058 Variable* variable = proxy->var(); 10020 Variable* variable = proxy->var();
10059 bool hole_init = mode == CONST || mode == CONST_HARMONY || mode == LET; 10021 bool hole_init = mode == LET || mode == CONST || mode == CONST_LEGACY;
10060 switch (variable->location()) { 10022 switch (variable->location()) {
10061 case Variable::UNALLOCATED: 10023 case Variable::UNALLOCATED:
10062 globals_.Add(variable->name(), zone()); 10024 globals_.Add(variable->name(), zone());
10063 globals_.Add(variable->binding_needs_init() 10025 globals_.Add(variable->binding_needs_init()
10064 ? isolate()->factory()->the_hole_value() 10026 ? isolate()->factory()->the_hole_value()
10065 : isolate()->factory()->undefined_value(), zone()); 10027 : isolate()->factory()->undefined_value(), zone());
10066 return; 10028 return;
10067 case Variable::PARAMETER: 10029 case Variable::PARAMETER:
10068 case Variable::LOCAL: 10030 case Variable::LOCAL:
10069 if (hole_init) { 10031 if (hole_init) {
(...skipping 427 matching lines...) Expand 10 before | Expand all | Expand 10 after
10497 HValue* right = Pop(); 10459 HValue* right = Pop();
10498 HValue* left = Pop(); 10460 HValue* left = Pop();
10499 HInstruction* result = NewUncasted<HStringAdd>(left, right); 10461 HInstruction* result = NewUncasted<HStringAdd>(left, right);
10500 return ast_context()->ReturnInstruction(result, call->id()); 10462 return ast_context()->ReturnInstruction(result, call->id());
10501 } 10463 }
10502 10464
10503 10465
10504 // Fast support for SubString. 10466 // Fast support for SubString.
10505 void HOptimizedGraphBuilder::GenerateSubString(CallRuntime* call) { 10467 void HOptimizedGraphBuilder::GenerateSubString(CallRuntime* call) {
10506 ASSERT_EQ(3, call->arguments()->length()); 10468 ASSERT_EQ(3, call->arguments()->length());
10507 CHECK_ALIVE(VisitArgumentList(call->arguments())); 10469 CHECK_ALIVE(VisitExpressions(call->arguments()));
10470 PushArgumentsFromEnvironment(call->arguments()->length());
10508 HCallStub* result = New<HCallStub>(CodeStub::SubString, 3); 10471 HCallStub* result = New<HCallStub>(CodeStub::SubString, 3);
10509 Drop(3);
10510 return ast_context()->ReturnInstruction(result, call->id()); 10472 return ast_context()->ReturnInstruction(result, call->id());
10511 } 10473 }
10512 10474
10513 10475
10514 // Fast support for StringCompare. 10476 // Fast support for StringCompare.
10515 void HOptimizedGraphBuilder::GenerateStringCompare(CallRuntime* call) { 10477 void HOptimizedGraphBuilder::GenerateStringCompare(CallRuntime* call) {
10516 ASSERT_EQ(2, call->arguments()->length()); 10478 ASSERT_EQ(2, call->arguments()->length());
10517 CHECK_ALIVE(VisitArgumentList(call->arguments())); 10479 CHECK_ALIVE(VisitExpressions(call->arguments()));
10480 PushArgumentsFromEnvironment(call->arguments()->length());
10518 HCallStub* result = New<HCallStub>(CodeStub::StringCompare, 2); 10481 HCallStub* result = New<HCallStub>(CodeStub::StringCompare, 2);
10519 Drop(2);
10520 return ast_context()->ReturnInstruction(result, call->id()); 10482 return ast_context()->ReturnInstruction(result, call->id());
10521 } 10483 }
10522 10484
10523 10485
10524 // Support for direct calls from JavaScript to native RegExp code. 10486 // Support for direct calls from JavaScript to native RegExp code.
10525 void HOptimizedGraphBuilder::GenerateRegExpExec(CallRuntime* call) { 10487 void HOptimizedGraphBuilder::GenerateRegExpExec(CallRuntime* call) {
10526 ASSERT_EQ(4, call->arguments()->length()); 10488 ASSERT_EQ(4, call->arguments()->length());
10527 CHECK_ALIVE(VisitArgumentList(call->arguments())); 10489 CHECK_ALIVE(VisitExpressions(call->arguments()));
10490 PushArgumentsFromEnvironment(call->arguments()->length());
10528 HCallStub* result = New<HCallStub>(CodeStub::RegExpExec, 4); 10491 HCallStub* result = New<HCallStub>(CodeStub::RegExpExec, 4);
10529 Drop(4);
10530 return ast_context()->ReturnInstruction(result, call->id()); 10492 return ast_context()->ReturnInstruction(result, call->id());
10531 } 10493 }
10532 10494
10495
10496 void HOptimizedGraphBuilder::GenerateDoubleLo(CallRuntime* call) {
10497 ASSERT_EQ(1, call->arguments()->length());
10498 CHECK_ALIVE(VisitForValue(call->arguments()->at(0)));
10499 HValue* value = Pop();
10500 HInstruction* result = NewUncasted<HDoubleBits>(value, HDoubleBits::LOW);
10501 return ast_context()->ReturnInstruction(result, call->id());
10502 }
10503
10504
10505 void HOptimizedGraphBuilder::GenerateDoubleHi(CallRuntime* call) {
10506 ASSERT_EQ(1, call->arguments()->length());
10507 CHECK_ALIVE(VisitForValue(call->arguments()->at(0)));
10508 HValue* value = Pop();
10509 HInstruction* result = NewUncasted<HDoubleBits>(value, HDoubleBits::HIGH);
10510 return ast_context()->ReturnInstruction(result, call->id());
10511 }
10512
10513
10514 void HOptimizedGraphBuilder::GenerateConstructDouble(CallRuntime* call) {
10515 ASSERT_EQ(2, call->arguments()->length());
10516 CHECK_ALIVE(VisitForValue(call->arguments()->at(0)));
10517 CHECK_ALIVE(VisitForValue(call->arguments()->at(1)));
10518 HValue* lo = Pop();
10519 HValue* hi = Pop();
10520 HInstruction* result = NewUncasted<HConstructDouble>(hi, lo);
10521 return ast_context()->ReturnInstruction(result, call->id());
10522 }
10523
10533 10524
10534 // Construct a RegExp exec result with two in-object properties. 10525 // Construct a RegExp exec result with two in-object properties.
10535 void HOptimizedGraphBuilder::GenerateRegExpConstructResult(CallRuntime* call) { 10526 void HOptimizedGraphBuilder::GenerateRegExpConstructResult(CallRuntime* call) {
10536 ASSERT_EQ(3, call->arguments()->length()); 10527 ASSERT_EQ(3, call->arguments()->length());
10537 CHECK_ALIVE(VisitForValue(call->arguments()->at(0))); 10528 CHECK_ALIVE(VisitForValue(call->arguments()->at(0)));
10538 CHECK_ALIVE(VisitForValue(call->arguments()->at(1))); 10529 CHECK_ALIVE(VisitForValue(call->arguments()->at(1)));
10539 CHECK_ALIVE(VisitForValue(call->arguments()->at(2))); 10530 CHECK_ALIVE(VisitForValue(call->arguments()->at(2)));
10540 HValue* input = Pop(); 10531 HValue* input = Pop();
10541 HValue* index = Pop(); 10532 HValue* index = Pop();
10542 HValue* length = Pop(); 10533 HValue* length = Pop();
(...skipping 17 matching lines...) Expand all
10560 return ast_context()->ReturnValue(result); 10551 return ast_context()->ReturnValue(result);
10561 } 10552 }
10562 10553
10563 10554
10564 // Fast call for custom callbacks. 10555 // Fast call for custom callbacks.
10565 void HOptimizedGraphBuilder::GenerateCallFunction(CallRuntime* call) { 10556 void HOptimizedGraphBuilder::GenerateCallFunction(CallRuntime* call) {
10566 // 1 ~ The function to call is not itself an argument to the call. 10557 // 1 ~ The function to call is not itself an argument to the call.
10567 int arg_count = call->arguments()->length() - 1; 10558 int arg_count = call->arguments()->length() - 1;
10568 ASSERT(arg_count >= 1); // There's always at least a receiver. 10559 ASSERT(arg_count >= 1); // There's always at least a receiver.
10569 10560
10570 for (int i = 0; i < arg_count; ++i) { 10561 CHECK_ALIVE(VisitExpressions(call->arguments()));
10571 CHECK_ALIVE(VisitArgument(call->arguments()->at(i))); 10562 // The function is the last argument
10572 }
10573 CHECK_ALIVE(VisitForValue(call->arguments()->last()));
10574
10575 HValue* function = Pop(); 10563 HValue* function = Pop();
10564 // Push the arguments to the stack
10565 PushArgumentsFromEnvironment(arg_count);
10576 10566
10577 IfBuilder if_is_jsfunction(this); 10567 IfBuilder if_is_jsfunction(this);
10578 if_is_jsfunction.If<HHasInstanceTypeAndBranch>(function, JS_FUNCTION_TYPE); 10568 if_is_jsfunction.If<HHasInstanceTypeAndBranch>(function, JS_FUNCTION_TYPE);
10579 10569
10580 if_is_jsfunction.Then(); 10570 if_is_jsfunction.Then();
10581 { 10571 {
10582 HInstruction* invoke_result = 10572 HInstruction* invoke_result =
10583 Add<HInvokeFunction>(function, arg_count); 10573 Add<HInvokeFunction>(function, arg_count);
10584 Drop(arg_count);
10585 if (!ast_context()->IsEffect()) { 10574 if (!ast_context()->IsEffect()) {
10586 Push(invoke_result); 10575 Push(invoke_result);
10587 } 10576 }
10588 Add<HSimulate>(call->id(), FIXED_SIMULATE); 10577 Add<HSimulate>(call->id(), FIXED_SIMULATE);
10589 } 10578 }
10590 10579
10591 if_is_jsfunction.Else(); 10580 if_is_jsfunction.Else();
10592 { 10581 {
10593 HInstruction* call_result = 10582 HInstruction* call_result =
10594 Add<HCallFunction>(function, arg_count); 10583 Add<HCallFunction>(function, arg_count);
10595 Drop(arg_count);
10596 if (!ast_context()->IsEffect()) { 10584 if (!ast_context()->IsEffect()) {
10597 Push(call_result); 10585 Push(call_result);
10598 } 10586 }
10599 Add<HSimulate>(call->id(), FIXED_SIMULATE); 10587 Add<HSimulate>(call->id(), FIXED_SIMULATE);
10600 } 10588 }
10601 if_is_jsfunction.End(); 10589 if_is_jsfunction.End();
10602 10590
10603 if (ast_context()->IsEffect()) { 10591 if (ast_context()->IsEffect()) {
10604 // EffectContext::ReturnValue ignores the value, so we can just pass 10592 // EffectContext::ReturnValue ignores the value, so we can just pass
10605 // 'undefined' (as we do not have the call result anymore). 10593 // 'undefined' (as we do not have the call result anymore).
(...skipping 692 matching lines...) Expand 10 before | Expand all | Expand 10 after
11298 if (ShouldProduceTraceOutput()) { 11286 if (ShouldProduceTraceOutput()) {
11299 isolate()->GetHTracer()->TraceHydrogen(name(), graph_); 11287 isolate()->GetHTracer()->TraceHydrogen(name(), graph_);
11300 } 11288 }
11301 11289
11302 #ifdef DEBUG 11290 #ifdef DEBUG
11303 graph_->Verify(false); // No full verify. 11291 graph_->Verify(false); // No full verify.
11304 #endif 11292 #endif
11305 } 11293 }
11306 11294
11307 } } // namespace v8::internal 11295 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « src/hydrogen.h ('k') | src/hydrogen-bce.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698