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

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: Sorted Lithium instructions names. 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
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 2937 matching lines...) Expand 10 before | Expand all | Expand 10 after
2948 } 2948 }
2949 if (lookup->type() != NORMAL) { 2949 if (lookup->type() != NORMAL) {
2950 BAILOUT("global variable has accessors"); 2950 BAILOUT("global variable has accessors");
2951 } 2951 }
2952 if (is_store && lookup->IsReadOnly()) { 2952 if (is_store && lookup->IsReadOnly()) {
2953 BAILOUT("read-only global variable"); 2953 BAILOUT("read-only global variable");
2954 } 2954 }
2955 } 2955 }
2956 2956
2957 2957
2958 HValue* HGraphBuilder::BuildContextChainWalk(Variable* var) {
2959 ASSERT(var->IsContextSlot());
2960 HInstruction* context = new HContext;
2961 AddInstruction(context);
2962 int length = graph()->info()->scope()->ContextChainLength(var->scope());
2963 while (length-- > 0) {
2964 context = new HOuterContext(context);
2965 AddInstruction(context);
2966 }
2967 return context;
2968 }
2969
2970
2958 void HGraphBuilder::VisitVariableProxy(VariableProxy* expr) { 2971 void HGraphBuilder::VisitVariableProxy(VariableProxy* expr) {
2959 Variable* variable = expr->AsVariable(); 2972 Variable* variable = expr->AsVariable();
2960 if (variable == NULL) { 2973 if (variable == NULL) {
2961 BAILOUT("reference to rewritten variable"); 2974 BAILOUT("reference to rewritten variable");
2962 } else if (variable->IsStackAllocated()) { 2975 } else if (variable->IsStackAllocated()) {
2963 if (environment()->Lookup(variable)->CheckFlag(HValue::kIsArguments)) { 2976 if (environment()->Lookup(variable)->CheckFlag(HValue::kIsArguments)) {
2964 BAILOUT("unsupported context for arguments object"); 2977 BAILOUT("unsupported context for arguments object");
2965 } 2978 }
2966 ast_context()->ReturnValue(environment()->Lookup(variable)); 2979 ast_context()->ReturnValue(environment()->Lookup(variable));
2967 } else if (variable->IsContextSlot()) { 2980 } else if (variable->IsContextSlot()) {
2968 if (variable->mode() == Variable::CONST) { 2981 if (variable->mode() == Variable::CONST) {
2969 BAILOUT("reference to const context slot"); 2982 BAILOUT("reference to const context slot");
2970 } 2983 }
2971 Slot* slot = variable->AsSlot(); 2984 HValue* context = BuildContextChainWalk(variable);
2972 CompilationInfo* info = graph()->info(); 2985 int index = variable->AsSlot()->index();
2973 int context_chain_length = info->function()->scope()-> 2986 HLoadContextSlot* instr = new HLoadContextSlot(context, index);
2974 ContextChainLength(slot->var()->scope());
2975 ASSERT(context_chain_length >= 0);
2976 // TODO(antonm): if slot's value is not modified by closures, instead
antonm 2011/02/03 13:14:30 may we keep this TODO?
2977 // of reading it out of context, we could just embed the value as
2978 // a constant.
2979 HLoadContextSlot* instr =
2980 new HLoadContextSlot(context_chain_length, slot->index());
2981 ast_context()->ReturnInstruction(instr, expr->id()); 2987 ast_context()->ReturnInstruction(instr, expr->id());
2982 } else if (variable->is_global()) { 2988 } else if (variable->is_global()) {
2983 LookupResult lookup; 2989 LookupResult lookup;
2984 LookupGlobalPropertyCell(variable, &lookup, false); 2990 LookupGlobalPropertyCell(variable, &lookup, false);
2985 CHECK_BAILOUT; 2991 CHECK_BAILOUT;
2986 2992
2987 Handle<GlobalObject> global(graph()->info()->global_object()); 2993 Handle<GlobalObject> global(graph()->info()->global_object());
2988 // TODO(3039103): Handle global property load through an IC call when access 2994 // TODO(3039103): Handle global property load through an IC call when access
2989 // checks are enabled. 2995 // checks are enabled.
2990 if (global->IsAccessCheckNeeded()) { 2996 if (global->IsAccessCheckNeeded()) {
(...skipping 517 matching lines...) Expand 10 before | Expand all | Expand 10 after
3508 3514
3509 if (expr->is_compound()) { 3515 if (expr->is_compound()) {
3510 HandleCompoundAssignment(expr); 3516 HandleCompoundAssignment(expr);
3511 return; 3517 return;
3512 } 3518 }
3513 3519
3514 if (var != NULL) { 3520 if (var != NULL) {
3515 if (proxy->IsArguments()) BAILOUT("assignment to arguments"); 3521 if (proxy->IsArguments()) BAILOUT("assignment to arguments");
3516 3522
3517 // Handle the assignment. 3523 // Handle the assignment.
3518 if (var->is_global()) { 3524 if (var->IsStackAllocated()) {
3525 HValue* value = NULL;
3526 // Handle stack-allocated variables on the right-hand side directly.
3527 // We do not allow the arguments object to occur in a context where it
3528 // may escape, but assignments to stack-allocated locals are
3529 // permitted. Handling such assignments here bypasses the check for
3530 // the arguments object in VisitVariableProxy.
3531 Variable* rhs_var = expr->value()->AsVariableProxy()->AsVariable();
3532 if (rhs_var != NULL && rhs_var->IsStackAllocated()) {
3533 value = environment()->Lookup(rhs_var);
3534 } else {
3535 VISIT_FOR_VALUE(expr->value());
3536 value = Pop();
3537 }
3538 Bind(var, value);
3539 ast_context()->ReturnValue(value);
3540
3541 } else if (var->IsContextSlot() && var->mode() != Variable::CONST) {
3542 VISIT_FOR_VALUE(expr->value());
3543 HValue* context = BuildContextChainWalk(var);
3544 int index = var->AsSlot()->index();
3545 HStoreContextSlot* instr = new HStoreContextSlot(context, index, Top());
3546 AddInstruction(instr);
3547 if (instr->HasSideEffects()) AddSimulate(expr->AssignmentId());
3548 ast_context()->ReturnValue(Pop());
3549
3550 } else if (var->is_global()) {
3519 VISIT_FOR_VALUE(expr->value()); 3551 VISIT_FOR_VALUE(expr->value());
3520 HandleGlobalVariableAssignment(var, 3552 HandleGlobalVariableAssignment(var,
3521 Top(), 3553 Top(),
3522 expr->position(), 3554 expr->position(),
3523 expr->AssignmentId()); 3555 expr->AssignmentId());
3524 } else if (var->IsStackAllocated()) { 3556 ast_context()->ReturnValue(Pop());
3525 // We allow reference to the arguments object only in assignemtns 3557
3526 // to local variables to make sure that the arguments object does
3527 // not escape and is not modified.
3528 VariableProxy* rhs = expr->value()->AsVariableProxy();
3529 if (rhs != NULL &&
3530 rhs->var()->IsStackAllocated() &&
3531 environment()->Lookup(rhs->var())->CheckFlag(HValue::kIsArguments)) {
3532 Push(environment()->Lookup(rhs->var()));
3533 } else {
3534 VISIT_FOR_VALUE(expr->value());
3535 }
3536 Bind(proxy->var(), Top());
3537 } else { 3558 } else {
3538 BAILOUT("Assigning to no non-stack-allocated/non-global variable"); 3559 BAILOUT("assignment to LOOKUP or const CONTEXT variable");
3539 } 3560 }
3540 // Return the value.
3541 ast_context()->ReturnValue(Pop());
3542 3561
3543 } else if (prop != NULL) { 3562 } else if (prop != NULL) {
3544 HandlePropertyAssignment(expr); 3563 HandlePropertyAssignment(expr);
3545 } else { 3564 } else {
3546 BAILOUT("unsupported invalid lhs"); 3565 BAILOUT("invalid left-hand side in assignment");
3547 } 3566 }
3548 } 3567 }
3549 3568
3550 3569
3551 void HGraphBuilder::VisitThrow(Throw* expr) { 3570 void HGraphBuilder::VisitThrow(Throw* expr) {
3552 // We don't optimize functions with invalid left-hand sides in 3571 // We don't optimize functions with invalid left-hand sides in
3553 // assignments, count operations, or for-in. Consequently throw can 3572 // assignments, count operations, or for-in. Consequently throw can
3554 // currently only occur in an effect context. 3573 // currently only occur in an effect context.
3555 ASSERT(ast_context()->IsEffect()); 3574 ASSERT(ast_context()->IsEffect());
3556 VISIT_FOR_VALUE(expr->exception()); 3575 VISIT_FOR_VALUE(expr->exception());
(...skipping 858 matching lines...) Expand 10 before | Expand all | Expand 10 after
4415 // access check is not enabled we assume that the function will not change 4434 // access check is not enabled we assume that the function will not change
4416 // and generate optimized code for calling the function. 4435 // and generate optimized code for calling the function.
4417 CompilationInfo* info = graph()->info(); 4436 CompilationInfo* info = graph()->info();
4418 bool known_global_function = info->has_global_object() && 4437 bool known_global_function = info->has_global_object() &&
4419 !info->global_object()->IsAccessCheckNeeded() && 4438 !info->global_object()->IsAccessCheckNeeded() &&
4420 expr->ComputeGlobalTarget(Handle<GlobalObject>(info->global_object()), 4439 expr->ComputeGlobalTarget(Handle<GlobalObject>(info->global_object()),
4421 var->name()); 4440 var->name());
4422 if (known_global_function) { 4441 if (known_global_function) {
4423 // Push the global object instead of the global receiver because 4442 // Push the global object instead of the global receiver because
4424 // code generated by the full code generator expects it. 4443 // code generated by the full code generator expects it.
4425 PushAndAdd(new HGlobalObject); 4444 HContext* context = new HContext;
4445 HGlobalObject* global_object = new HGlobalObject(context);
4446 AddInstruction(context);
4447 PushAndAdd(global_object);
4426 VisitArgumentList(expr->arguments()); 4448 VisitArgumentList(expr->arguments());
4427 CHECK_BAILOUT; 4449 CHECK_BAILOUT;
4428 4450
4429 VISIT_FOR_VALUE(expr->expression()); 4451 VISIT_FOR_VALUE(expr->expression());
4430 HValue* function = Pop(); 4452 HValue* function = Pop();
4431 AddInstruction(new HCheckFunction(function, expr->target())); 4453 AddInstruction(new HCheckFunction(function, expr->target()));
4432 4454
4433 // Replace the global object with the global receiver. 4455 // Replace the global object with the global receiver.
4434 HGlobalReceiver* global_receiver = new HGlobalReceiver; 4456 HGlobalReceiver* global_receiver = new HGlobalReceiver(global_object);
4435 // Index of the receiver from the top of the expression stack. 4457 // Index of the receiver from the top of the expression stack.
4436 const int receiver_index = argument_count - 1; 4458 const int receiver_index = argument_count - 1;
4437 AddInstruction(global_receiver); 4459 AddInstruction(global_receiver);
4438 ASSERT(environment()->ExpressionStackAt(receiver_index)-> 4460 ASSERT(environment()->ExpressionStackAt(receiver_index)->
4439 IsGlobalObject()); 4461 IsGlobalObject());
4440 environment()->SetExpressionStackAt(receiver_index, global_receiver); 4462 environment()->SetExpressionStackAt(receiver_index, global_receiver);
4441 4463
4442 if (TryInline(expr)) { 4464 if (TryInline(expr)) {
4443 if (subgraph()->HasExit()) { 4465 if (subgraph()->HasExit()) {
4444 HValue* return_value = Pop(); 4466 HValue* return_value = Pop();
4445 // If we inlined a function in a test context then we need to 4467 // If we inlined a function in a test context then we need to
4446 // emit a simulate here to shadow the ones at the end of the 4468 // emit a simulate here to shadow the ones at the end of the
4447 // predecessor blocks. Those environments contain the return 4469 // predecessor blocks. Those environments contain the return
4448 // value on top and do not correspond to any actual state of the 4470 // value on top and do not correspond to any actual state of the
4449 // unoptimized code. 4471 // unoptimized code.
4450 if (ast_context()->IsEffect()) AddSimulate(expr->id()); 4472 if (ast_context()->IsEffect()) AddSimulate(expr->id());
4451 ast_context()->ReturnValue(return_value); 4473 ast_context()->ReturnValue(return_value);
4452 } 4474 }
4453 return; 4475 return;
4454 } 4476 }
4455 // Check for bailout, as trying to inline might fail due to bailout 4477 // Check for bailout, as trying to inline might fail due to bailout
4456 // during hydrogen processing. 4478 // during hydrogen processing.
4457 CHECK_BAILOUT; 4479 CHECK_BAILOUT;
4458 4480
4459 call = new HCallKnownGlobal(expr->target(), argument_count); 4481 call = new HCallKnownGlobal(expr->target(), argument_count);
4460 } else { 4482 } else {
4461 PushAndAdd(new HGlobalObject); 4483 HContext* context = new HContext;
4484 AddInstruction(context);
4485 PushAndAdd(new HGlobalObject(context));
4462 VisitArgumentList(expr->arguments()); 4486 VisitArgumentList(expr->arguments());
4463 CHECK_BAILOUT; 4487 CHECK_BAILOUT;
4464 4488
4465 call = new HCallGlobal(var->name(), argument_count); 4489 call = new HCallGlobal(var->name(), argument_count);
4466 } 4490 }
4467 4491
4468 } else { 4492 } else {
4469 PushAndAdd(new HGlobalReceiver); 4493 HContext* context = new HContext;
4494 HGlobalObject* global_object = new HGlobalObject(context);
4495 AddInstruction(context);
4496 AddInstruction(global_object);
4497 PushAndAdd(new HGlobalReceiver(global_object));
4470 VisitArgumentList(expr->arguments()); 4498 VisitArgumentList(expr->arguments());
4471 CHECK_BAILOUT; 4499 CHECK_BAILOUT;
4472 4500
4473 call = new HCallFunction(argument_count); 4501 call = new HCallFunction(argument_count);
4474 } 4502 }
4475 } 4503 }
4476 4504
4477 call->set_position(expr->position()); 4505 call->set_position(expr->position());
4478 ProcessCall(call); 4506 ProcessCall(call);
4479 ast_context()->ReturnInstruction(call, expr->id()); 4507 ast_context()->ReturnInstruction(call, expr->id());
(...skipping 1416 matching lines...) Expand 10 before | Expand all | Expand 10 after
5896 } 5924 }
5897 } 5925 }
5898 5926
5899 #ifdef DEBUG 5927 #ifdef DEBUG
5900 if (graph_ != NULL) graph_->Verify(); 5928 if (graph_ != NULL) graph_->Verify();
5901 if (allocator_ != NULL) allocator_->Verify(); 5929 if (allocator_ != NULL) allocator_->Verify();
5902 #endif 5930 #endif
5903 } 5931 }
5904 5932
5905 } } // namespace v8::internal 5933 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « src/hydrogen.h ('k') | src/hydrogen-instructions.h » ('j') | src/ia32/lithium-ia32.cc » ('J')

Powered by Google App Engine
This is Rietveld 408576698