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

Side by Side Diff: src/hydrogen.cc

Issue 8857001: [hydrogen] don't bailout assignments to consts (Closed) Base URL: gh:v8/v8@master
Patch Set: [arm] fixed illegal access errorwq Created 9 years 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
OLDNEW
1 // Copyright 2011 the V8 project authors. All rights reserved. 1 // Copyright 2011 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 3270 matching lines...) Expand 10 before | Expand all | Expand 10 after
3281 variable->mode() == LET); 3281 variable->mode() == LET);
3282 return Bailout("reference to uninitialized variable"); 3282 return Bailout("reference to uninitialized variable");
3283 } 3283 }
3284 return ast_context()->ReturnValue(value); 3284 return ast_context()->ReturnValue(value);
3285 } 3285 }
3286 3286
3287 case Variable::CONTEXT: { 3287 case Variable::CONTEXT: {
3288 if (variable->mode() == LET || variable->mode() == CONST_HARMONY) { 3288 if (variable->mode() == LET || variable->mode() == CONST_HARMONY) {
3289 return Bailout("reference to harmony declared context slot"); 3289 return Bailout("reference to harmony declared context slot");
3290 } 3290 }
3291 if (variable->mode() == CONST) {
3292 return Bailout("reference to const context slot");
3293 }
3294 HValue* context = BuildContextChainWalk(variable); 3291 HValue* context = BuildContextChainWalk(variable);
3295 HLoadContextSlot* instr = 3292 HLoadContextSlot* instr =
3296 new(zone()) HLoadContextSlot(context, variable->index()); 3293 new(zone()) HLoadContextSlot(context, variable->index());
3294 if (variable->mode() == CONST) {
3295 instr->ForceIsHoleCheck();
3296 }
3297 return ast_context()->ReturnInstruction(instr, expr->id()); 3297 return ast_context()->ReturnInstruction(instr, expr->id());
3298 } 3298 }
3299 3299
3300 case Variable::LOOKUP: 3300 case Variable::LOOKUP:
3301 return Bailout("reference to a variable which requires dynamic lookup"); 3301 return Bailout("reference to a variable which requires dynamic lookup");
3302 } 3302 }
3303 } 3303 }
3304 3304
3305 3305
3306 void HGraphBuilder::VisitLiteral(Literal* expr) { 3306 void HGraphBuilder::VisitLiteral(Literal* expr) {
(...skipping 642 matching lines...) Expand 10 before | Expand all | Expand 10 after
3949 3949
3950 if (expr->is_compound()) { 3950 if (expr->is_compound()) {
3951 HandleCompoundAssignment(expr); 3951 HandleCompoundAssignment(expr);
3952 return; 3952 return;
3953 } 3953 }
3954 3954
3955 if (prop != NULL) { 3955 if (prop != NULL) {
3956 HandlePropertyAssignment(expr); 3956 HandlePropertyAssignment(expr);
3957 } else if (proxy != NULL) { 3957 } else if (proxy != NULL) {
3958 Variable* var = proxy->var(); 3958 Variable* var = proxy->var();
3959
3959 if (var->mode() == CONST) { 3960 if (var->mode() == CONST) {
3960 if (expr->op() != Token::INIT_CONST) { 3961 if (expr->op() != Token::INIT_CONST) {
3961 return Bailout("non-initializer assignment to const"); 3962 CHECK_ALIVE(VisitForValue(expr->value()));
3963 return ast_context()->ReturnValue(Pop());
3962 } 3964 }
3963 if (!var->IsStackAllocated()) { 3965
3964 return Bailout("assignment to const context slot"); 3966 if (var->IsStackAllocated()) {
3965 } 3967 // We insert a use of the old value to detect unsupported uses of const
3966 // We insert a use of the old value to detect unsupported uses of const 3968 // variables (e.g. initialization inside a loop).
3967 // variables (e.g. initialization inside a loop). 3969 HValue* old_value = environment()->Lookup(var);
3968 HValue* old_value = environment()->Lookup(var); 3970 AddInstruction(new HUseConst(old_value));
3969 AddInstruction(new HUseConst(old_value));
3970 } else if (var->mode() == LET) {
3971 if (!var->IsStackAllocated()) {
3972 return Bailout("assignment to let context slot");
3973 } 3971 }
3974 } else if (var->mode() == CONST_HARMONY) { 3972 } else if (var->mode() == CONST_HARMONY) {
3975 if (expr->op() != Token::INIT_CONST_HARMONY) { 3973 if (expr->op() != Token::INIT_CONST_HARMONY) {
3976 return Bailout("non-initializer assignment to const"); 3974 return Bailout("non-initializer assignment to const");
3977 } 3975 }
3978 if (!var->IsStackAllocated()) { 3976 if (!var->IsStackAllocated()) {
3979 return Bailout("assignment to const context slot"); 3977 return Bailout("assignment to const context slot");
3980 } 3978 }
3979 } else if (var->mode() == LET) {
3980 if (!var->IsStackAllocated()) {
3981 return Bailout("assignment to let context slot");
3982 }
3981 } 3983 }
3982 3984
3983 if (proxy->IsArguments()) return Bailout("assignment to arguments"); 3985 if (proxy->IsArguments()) return Bailout("assignment to arguments");
3984 3986
3985 // Handle the assignment. 3987 // Handle the assignment.
3986 switch (var->location()) { 3988 switch (var->location()) {
3987 case Variable::UNALLOCATED: 3989 case Variable::UNALLOCATED:
3988 CHECK_ALIVE(VisitForValue(expr->value())); 3990 CHECK_ALIVE(VisitForValue(expr->value()));
3989 HandleGlobalVariableAssignment(var, 3991 HandleGlobalVariableAssignment(var,
3990 Top(), 3992 Top(),
(...skipping 14 matching lines...) Expand all
4005 // We do not allow the arguments object to occur in a context where it 4007 // We do not allow the arguments object to occur in a context where it
4006 // may escape, but assignments to stack-allocated locals are 4008 // may escape, but assignments to stack-allocated locals are
4007 // permitted. 4009 // permitted.
4008 CHECK_ALIVE(VisitForValue(expr->value(), ARGUMENTS_ALLOWED)); 4010 CHECK_ALIVE(VisitForValue(expr->value(), ARGUMENTS_ALLOWED));
4009 HValue* value = Pop(); 4011 HValue* value = Pop();
4010 Bind(var, value); 4012 Bind(var, value);
4011 return ast_context()->ReturnValue(value); 4013 return ast_context()->ReturnValue(value);
4012 } 4014 }
4013 4015
4014 case Variable::CONTEXT: { 4016 case Variable::CONTEXT: {
4015 ASSERT(var->mode() != CONST);
4016 // Bail out if we try to mutate a parameter value in a function using 4017 // Bail out if we try to mutate a parameter value in a function using
4017 // the arguments object. We do not (yet) correctly handle the 4018 // the arguments object. We do not (yet) correctly handle the
4018 // arguments property of the function. 4019 // arguments property of the function.
4019 if (info()->scope()->arguments() != NULL) { 4020 if (info()->scope()->arguments() != NULL) {
4020 // Parameters will rewrite to context slots. We have no direct way 4021 // Parameters will rewrite to context slots. We have no direct way
4021 // to detect that the variable is a parameter. 4022 // to detect that the variable is a parameter.
4022 int count = info()->scope()->num_parameters(); 4023 int count = info()->scope()->num_parameters();
4023 for (int i = 0; i < count; ++i) { 4024 for (int i = 0; i < count; ++i) {
4024 if (var == info()->scope()->parameter(i)) { 4025 if (var == info()->scope()->parameter(i)) {
4025 return Bailout("assignment to parameter in arguments object"); 4026 return Bailout("assignment to parameter in arguments object");
4026 } 4027 }
4027 } 4028 }
4028 } 4029 }
4029 4030
4030 CHECK_ALIVE(VisitForValue(expr->value())); 4031 CHECK_ALIVE(VisitForValue(expr->value()));
4031 HValue* context = BuildContextChainWalk(var); 4032 HValue* context = BuildContextChainWalk(var);
4032 HStoreContextSlot* instr = 4033 HStoreContextSlot* instr =
4033 new(zone()) HStoreContextSlot(context, var->index(), Top()); 4034 new(zone()) HStoreContextSlot(context, var->index(), Top());
4035
4036 // Ensure that const variable's value will be set only once
4037 if (var->mode() == CONST) {
4038 instr->ForceIsHoleCheck();
4039 }
4040
4034 AddInstruction(instr); 4041 AddInstruction(instr);
4035 if (instr->HasObservableSideEffects()) { 4042 if (instr->HasObservableSideEffects()) {
4036 AddSimulate(expr->AssignmentId()); 4043 AddSimulate(expr->AssignmentId());
4037 } 4044 }
4038 return ast_context()->ReturnValue(Pop()); 4045 return ast_context()->ReturnValue(Pop());
4039 } 4046 }
4040 4047
4041 case Variable::LOOKUP: 4048 case Variable::LOOKUP:
4042 return Bailout("assignment to LOOKUP variable"); 4049 return Bailout("assignment to LOOKUP variable");
4043 } 4050 }
(...skipping 3204 matching lines...) Expand 10 before | Expand all | Expand 10 after
7248 } 7255 }
7249 } 7256 }
7250 7257
7251 #ifdef DEBUG 7258 #ifdef DEBUG
7252 if (graph_ != NULL) graph_->Verify(false); // No full verify. 7259 if (graph_ != NULL) graph_->Verify(false); // No full verify.
7253 if (allocator_ != NULL) allocator_->Verify(); 7260 if (allocator_ != NULL) allocator_->Verify();
7254 #endif 7261 #endif
7255 } 7262 }
7256 7263
7257 } } // namespace v8::internal 7264 } } // namespace v8::internal
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698