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

Side by Side Diff: src/hydrogen.cc

Issue 6390003: Introduce a hydrogen value for contexts, support context slot assignment. (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Created 9 years, 10 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 | « no previous file | src/hydrogen-instructions.h » ('j') | src/hydrogen-instructions.h » ('J')
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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 2934 matching lines...) Expand 10 before | Expand all | Expand 10 after
2945 BAILOUT("reference to rewritten variable"); 2945 BAILOUT("reference to rewritten variable");
2946 } else if (variable->IsStackAllocated()) { 2946 } else if (variable->IsStackAllocated()) {
2947 if (environment()->Lookup(variable)->CheckFlag(HValue::kIsArguments)) { 2947 if (environment()->Lookup(variable)->CheckFlag(HValue::kIsArguments)) {
2948 BAILOUT("unsupported context for arguments object"); 2948 BAILOUT("unsupported context for arguments object");
2949 } 2949 }
2950 ast_context()->ReturnValue(environment()->Lookup(variable)); 2950 ast_context()->ReturnValue(environment()->Lookup(variable));
2951 } else if (variable->IsContextSlot()) { 2951 } else if (variable->IsContextSlot()) {
2952 if (variable->mode() == Variable::CONST) { 2952 if (variable->mode() == Variable::CONST) {
2953 BAILOUT("reference to const context slot"); 2953 BAILOUT("reference to const context slot");
2954 } 2954 }
2955 Slot* slot = variable->AsSlot(); 2955 int context_chain_length =
2956 CompilationInfo* info = graph()->info(); 2956 graph()->info()->scope()->ContextChainLength(variable->scope());
2957 int context_chain_length = info->function()->scope()-> 2957 int index = variable->AsSlot()->index();
2958 ContextChainLength(slot->var()->scope());
2959 ASSERT(context_chain_length >= 0);
2960 // TODO(antonm): if slot's value is not modified by closures, instead 2958 // TODO(antonm): if slot's value is not modified by closures, instead
2961 // of reading it out of context, we could just embed the value as 2959 // of reading it out of context, we could just embed the value as
2962 // a constant. 2960 // a constant.
2963 HLoadContextSlot* instr = 2961 HInstruction* context = new HContext;
2964 new HLoadContextSlot(context_chain_length, slot->index()); 2962 AddInstruction(context);
2963 for (int i = 0; i < context_chain_length; ++i) {
2964 context = new HOuterContext(context);
2965 AddInstruction(context);
2966 }
2967 HLoadContextSlot* instr = new HLoadContextSlot(context, index);
2965 ast_context()->ReturnInstruction(instr, expr->id()); 2968 ast_context()->ReturnInstruction(instr, expr->id());
2966 } else if (variable->is_global()) { 2969 } else if (variable->is_global()) {
2967 LookupResult lookup; 2970 LookupResult lookup;
2968 LookupGlobalPropertyCell(variable, &lookup, false); 2971 LookupGlobalPropertyCell(variable, &lookup, false);
2969 CHECK_BAILOUT; 2972 CHECK_BAILOUT;
2970 2973
2971 Handle<GlobalObject> global(graph()->info()->global_object()); 2974 Handle<GlobalObject> global(graph()->info()->global_object());
2972 // TODO(3039103): Handle global property load through an IC call when access 2975 // TODO(3039103): Handle global property load through an IC call when access
2973 // checks are enabled. 2976 // checks are enabled.
2974 if (global->IsAccessCheckNeeded()) { 2977 if (global->IsAccessCheckNeeded()) {
(...skipping 518 matching lines...) Expand 10 before | Expand all | Expand 10 after
3493 3496
3494 if (expr->is_compound()) { 3497 if (expr->is_compound()) {
3495 HandleCompoundAssignment(expr); 3498 HandleCompoundAssignment(expr);
3496 return; 3499 return;
3497 } 3500 }
3498 3501
3499 if (var != NULL) { 3502 if (var != NULL) {
3500 if (proxy->IsArguments()) BAILOUT("assignment to arguments"); 3503 if (proxy->IsArguments()) BAILOUT("assignment to arguments");
3501 3504
3502 // Handle the assignment. 3505 // Handle the assignment.
3503 if (var->is_global()) { 3506 if (var->IsStackAllocated()) {
3507 HValue* value = NULL;
3508 // Handle stack-allocated variables on the right-hand side directly.
3509 // We do not allow the arguments object to occur in a context where it
3510 // may escape, but assignments to stack-allocated locals are
3511 // permitted. Handling such assignments here bypasses the check for
3512 // the arguments object in VisitVariableProxy.
3513 Variable* rhs_var = expr->value()->AsVariableProxy()->AsVariable();
3514 if (rhs_var != NULL && rhs_var->IsStackAllocated()) {
3515 value = environment()->Lookup(rhs_var);
3516 } else {
3517 VISIT_FOR_VALUE(expr->value());
3518 value = Pop();
3519 }
3520 Bind(var, value);
3521 ast_context()->ReturnValue(value);
3522
3523 } else if (var->IsContextSlot() && var->mode() != Variable::CONST) {
3524 int context_chain_length =
antonm 2011/01/27 14:00:07 should we refactor the code that builds context va
Kevin Millikin (Chromium) 2011/02/03 08:37:23 Yes, because we'll need it for compound assignment
3525 graph()->info()->scope()->ContextChainLength(var->scope());
3526 int index = var->AsSlot()->index();
3527 HInstruction* context = new HContext;
3528 AddInstruction(context);
3529 for (int i = 0; i < context_chain_length; ++i) {
3530 context = new HOuterContext(context);
3531 AddInstruction(context);
3532 }
3533 VISIT_FOR_VALUE(expr->value());
3534 HStoreContextSlot* instr = new HStoreContextSlot(context, index, Top());
3535 AddInstruction(instr);
3536 if (instr->HasSideEffects()) AddSimulate(expr->AssignmentId());
3537 ast_context()->ReturnValue(Pop());
3538
3539 } else if (var->is_global()) {
3504 VISIT_FOR_VALUE(expr->value()); 3540 VISIT_FOR_VALUE(expr->value());
3505 HandleGlobalVariableAssignment(var, 3541 HandleGlobalVariableAssignment(var,
3506 Top(), 3542 Top(),
3507 expr->position(), 3543 expr->position(),
3508 expr->AssignmentId()); 3544 expr->AssignmentId());
3509 } else if (var->IsStackAllocated()) { 3545 ast_context()->ReturnValue(Pop());
3510 // We allow reference to the arguments object only in assignemtns 3546
3511 // to local variables to make sure that the arguments object does
3512 // not escape and is not modified.
3513 VariableProxy* rhs = expr->value()->AsVariableProxy();
3514 if (rhs != NULL &&
3515 rhs->var()->IsStackAllocated() &&
3516 environment()->Lookup(rhs->var())->CheckFlag(HValue::kIsArguments)) {
3517 Push(environment()->Lookup(rhs->var()));
3518 } else {
3519 VISIT_FOR_VALUE(expr->value());
3520 }
3521 Bind(proxy->var(), Top());
3522 } else { 3547 } else {
3523 BAILOUT("Assigning to no non-stack-allocated/non-global variable"); 3548 BAILOUT("assignment to LOOKUP or const CONTEXT variable");
3524 } 3549 }
3525 // Return the value.
3526 ast_context()->ReturnValue(Pop());
3527 3550
3528 } else if (prop != NULL) { 3551 } else if (prop != NULL) {
3529 HandlePropertyAssignment(expr); 3552 HandlePropertyAssignment(expr);
3530 } else { 3553 } else {
3531 BAILOUT("unsupported invalid lhs"); 3554 BAILOUT("invalid left-hand side in assignment");
3532 } 3555 }
3533 } 3556 }
3534 3557
3535 3558
3536 void HGraphBuilder::VisitThrow(Throw* expr) { 3559 void HGraphBuilder::VisitThrow(Throw* expr) {
3537 // We don't optimize functions with invalid left-hand sides in 3560 // We don't optimize functions with invalid left-hand sides in
3538 // assignments, count operations, or for-in. Consequently throw can 3561 // assignments, count operations, or for-in. Consequently throw can
3539 // currently only occur in an effect context. 3562 // currently only occur in an effect context.
3540 ASSERT(ast_context()->IsEffect()); 3563 ASSERT(ast_context()->IsEffect());
3541 VISIT_FOR_VALUE(expr->exception()); 3564 VISIT_FOR_VALUE(expr->exception());
(...skipping 856 matching lines...) Expand 10 before | Expand all | Expand 10 after
4398 // access check is not enabled we assume that the function will not change 4421 // access check is not enabled we assume that the function will not change
4399 // and generate optimized code for calling the function. 4422 // and generate optimized code for calling the function.
4400 CompilationInfo* info = graph()->info(); 4423 CompilationInfo* info = graph()->info();
4401 bool known_global_function = info->has_global_object() && 4424 bool known_global_function = info->has_global_object() &&
4402 !info->global_object()->IsAccessCheckNeeded() && 4425 !info->global_object()->IsAccessCheckNeeded() &&
4403 expr->ComputeGlobalTarget(Handle<GlobalObject>(info->global_object()), 4426 expr->ComputeGlobalTarget(Handle<GlobalObject>(info->global_object()),
4404 var->name()); 4427 var->name());
4405 if (known_global_function) { 4428 if (known_global_function) {
4406 // Push the global object instead of the global receiver because 4429 // Push the global object instead of the global receiver because
4407 // code generated by the full code generator expects it. 4430 // code generated by the full code generator expects it.
4408 PushAndAdd(new HGlobalObject); 4431 HContext* context = new HContext;
4432 HGlobalObject* global_object = new HGlobalObject(context);
4433 AddInstruction(context);
4434 PushAndAdd(global_object);
4409 VisitArgumentList(expr->arguments()); 4435 VisitArgumentList(expr->arguments());
4410 CHECK_BAILOUT; 4436 CHECK_BAILOUT;
4411 4437
4412 VISIT_FOR_VALUE(expr->expression()); 4438 VISIT_FOR_VALUE(expr->expression());
4413 HValue* function = Pop(); 4439 HValue* function = Pop();
4414 AddInstruction(new HCheckFunction(function, expr->target())); 4440 AddInstruction(new HCheckFunction(function, expr->target()));
4415 4441
4416 // Replace the global object with the global receiver. 4442 // Replace the global object with the global receiver.
4417 HGlobalReceiver* global_receiver = new HGlobalReceiver; 4443 HGlobalReceiver* global_receiver = new HGlobalReceiver(global_object);
4418 // Index of the receiver from the top of the expression stack. 4444 // Index of the receiver from the top of the expression stack.
4419 const int receiver_index = argument_count - 1; 4445 const int receiver_index = argument_count - 1;
4420 AddInstruction(global_receiver); 4446 AddInstruction(global_receiver);
4421 ASSERT(environment()->ExpressionStackAt(receiver_index)-> 4447 ASSERT(environment()->ExpressionStackAt(receiver_index)->
4422 IsGlobalObject()); 4448 IsGlobalObject());
4423 environment()->SetExpressionStackAt(receiver_index, global_receiver); 4449 environment()->SetExpressionStackAt(receiver_index, global_receiver);
4424 4450
4425 if (TryInline(expr)) { 4451 if (TryInline(expr)) {
4426 if (subgraph()->HasExit()) { 4452 if (subgraph()->HasExit()) {
4427 HValue* return_value = Pop(); 4453 HValue* return_value = Pop();
4428 // If we inlined a function in a test context then we need to 4454 // If we inlined a function in a test context then we need to
4429 // emit a simulate here to shadow the ones at the end of the 4455 // emit a simulate here to shadow the ones at the end of the
4430 // predecessor blocks. Those environments contain the return 4456 // predecessor blocks. Those environments contain the return
4431 // value on top and do not correspond to any actual state of the 4457 // value on top and do not correspond to any actual state of the
4432 // unoptimized code. 4458 // unoptimized code.
4433 if (ast_context()->IsEffect()) AddSimulate(expr->id()); 4459 if (ast_context()->IsEffect()) AddSimulate(expr->id());
4434 ast_context()->ReturnValue(return_value); 4460 ast_context()->ReturnValue(return_value);
4435 } 4461 }
4436 return; 4462 return;
4437 } 4463 }
4438 // Check for bailout, as trying to inline might fail due to bailout 4464 // Check for bailout, as trying to inline might fail due to bailout
4439 // during hydrogen processing. 4465 // during hydrogen processing.
4440 CHECK_BAILOUT; 4466 CHECK_BAILOUT;
4441 4467
4442 call = new HCallKnownGlobal(expr->target(), argument_count); 4468 call = new HCallKnownGlobal(expr->target(), argument_count);
4443 } else { 4469 } else {
4444 PushAndAdd(new HGlobalObject); 4470 HContext* context = new HContext;
4471 AddInstruction(context);
4472 PushAndAdd(new HGlobalObject(context));
4445 VisitArgumentList(expr->arguments()); 4473 VisitArgumentList(expr->arguments());
4446 CHECK_BAILOUT; 4474 CHECK_BAILOUT;
4447 4475
4448 call = new HCallGlobal(var->name(), argument_count); 4476 call = new HCallGlobal(var->name(), argument_count);
4449 } 4477 }
4450 4478
4451 } else { 4479 } else {
4452 PushAndAdd(new HGlobalReceiver); 4480 HContext* context = new HContext;
4481 HGlobalObject* global_object = new HGlobalObject(context);
4482 AddInstruction(context);
4483 AddInstruction(global_object);
4484 PushAndAdd(new HGlobalReceiver(global_object));
4453 VisitArgumentList(expr->arguments()); 4485 VisitArgumentList(expr->arguments());
4454 CHECK_BAILOUT; 4486 CHECK_BAILOUT;
4455 4487
4456 call = new HCallFunction(argument_count); 4488 call = new HCallFunction(argument_count);
4457 } 4489 }
4458 } 4490 }
4459 4491
4460 call->set_position(expr->position()); 4492 call->set_position(expr->position());
4461 ProcessCall(call); 4493 ProcessCall(call);
4462 ast_context()->ReturnInstruction(call, expr->id()); 4494 ast_context()->ReturnInstruction(call, expr->id());
(...skipping 1416 matching lines...) Expand 10 before | Expand all | Expand 10 after
5879 } 5911 }
5880 } 5912 }
5881 5913
5882 #ifdef DEBUG 5914 #ifdef DEBUG
5883 if (graph_ != NULL) graph_->Verify(); 5915 if (graph_ != NULL) graph_->Verify();
5884 if (allocator_ != NULL) allocator_->Verify(); 5916 if (allocator_ != NULL) allocator_->Verify();
5885 #endif 5917 #endif
5886 } 5918 }
5887 5919
5888 } } // namespace v8::internal 5920 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « no previous file | src/hydrogen-instructions.h » ('j') | src/hydrogen-instructions.h » ('J')

Powered by Google App Engine
This is Rietveld 408576698