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

Side by Side Diff: src/hydrogen.cc

Issue 6606006: [Isolates] Merge 6500:6700 from bleeding_edge to isolates. (Closed) Base URL: http://v8.googlecode.com/svn/branches/experimental/isolates/
Patch Set: '' Created 9 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-instructions.h » ('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 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 852 matching lines...) Expand 10 before | Expand all | Expand 10 after
863 } 863 }
864 } 864 }
865 // Replace the uses and add phis modified to the work list. 865 // Replace the uses and add phis modified to the work list.
866 for (int i = 0; i < uses_to_replace.length(); ++i) { 866 for (int i = 0; i < uses_to_replace.length(); ++i) {
867 HValue* use = uses_to_replace[i]; 867 HValue* use = uses_to_replace[i];
868 phi->ReplaceAtUse(use, value); 868 phi->ReplaceAtUse(use, value);
869 if (use->IsPhi()) worklist.Add(HPhi::cast(use)); 869 if (use->IsPhi()) worklist.Add(HPhi::cast(use));
870 } 870 }
871 uses_to_replace.Rewind(0); 871 uses_to_replace.Rewind(0);
872 block->RemovePhi(phi); 872 block->RemovePhi(phi);
873 } else if (phi->HasNoUses() && 873 } else if (FLAG_eliminate_dead_phis && phi->HasNoUses() &&
874 !phi->HasReceiverOperand() && 874 !phi->IsReceiver()) {
875 FLAG_eliminate_dead_phis) { 875 // We can't eliminate phis in the receiver position in the environment
876 // We can't eliminate phis that have the receiver as an operand 876 // because in case of throwing an error we need this value to
877 // because in case of throwing an error we need the correct 877 // construct a stack trace.
878 // receiver value in the environment to construct a corrent
879 // stack trace.
880 block->RemovePhi(phi); 878 block->RemovePhi(phi);
881 block->RecordDeletedPhi(phi->merged_index()); 879 block->RecordDeletedPhi(phi->merged_index());
882 } 880 }
883 } 881 }
884 } 882 }
885 883
886 884
887 bool HGraph::CollectPhis() { 885 bool HGraph::CollectPhis() {
888 const ZoneList<HBasicBlock*>* blocks = graph_->blocks(); 886 const ZoneList<HBasicBlock*>* blocks = graph_->blocks();
889 phi_list_ = new ZoneList<HPhi*>(blocks->length()); 887 phi_list_ = new ZoneList<HPhi*>(blocks->length());
(...skipping 916 matching lines...) Expand 10 before | Expand all | Expand 10 after
1806 1804
1807 current = current->EnsureAndPropagateNotMinusZero(visited); 1805 current = current->EnsureAndPropagateNotMinusZero(visited);
1808 } 1806 }
1809 } 1807 }
1810 1808
1811 1809
1812 void HGraph::InsertRepresentationChangeForUse(HValue* value, 1810 void HGraph::InsertRepresentationChangeForUse(HValue* value,
1813 HValue* use, 1811 HValue* use,
1814 Representation to, 1812 Representation to,
1815 bool is_truncating) { 1813 bool is_truncating) {
1816 // Propagate flags for negative zero checks upwards from conversions
1817 // int32-to-tagged and int32-to-double.
1818 Representation from = value->representation();
1819 if (from.IsInteger32()) {
1820 ASSERT(to.IsTagged() || to.IsDouble());
1821 BitVector visited(GetMaximumValueID());
1822 PropagateMinusZeroChecks(value, &visited);
1823 }
1824
1825 // Insert the representation change right before its use. For phi-uses we 1814 // Insert the representation change right before its use. For phi-uses we
1826 // insert at the end of the corresponding predecessor. 1815 // insert at the end of the corresponding predecessor.
1827 HBasicBlock* insert_block = use->block(); 1816 HBasicBlock* insert_block = use->block();
1828 if (use->IsPhi()) { 1817 if (use->IsPhi()) {
1829 int index = 0; 1818 int index = 0;
1830 while (use->OperandAt(index) != value) ++index; 1819 while (use->OperandAt(index) != value) ++index;
1831 insert_block = insert_block->predecessors()->at(index); 1820 insert_block = insert_block->predecessors()->at(index);
1832 } 1821 }
1833 1822
1834 HInstruction* next = (insert_block == use->block()) 1823 HInstruction* next = (insert_block == use->block())
(...skipping 142 matching lines...) Expand 10 before | Expand all | Expand 10 after
1977 // Process normal instructions. 1966 // Process normal instructions.
1978 HInstruction* current = blocks_[i]->first(); 1967 HInstruction* current = blocks_[i]->first();
1979 while (current != NULL) { 1968 while (current != NULL) {
1980 InsertRepresentationChanges(current); 1969 InsertRepresentationChanges(current);
1981 current = current->next(); 1970 current = current->next();
1982 } 1971 }
1983 } 1972 }
1984 } 1973 }
1985 1974
1986 1975
1976 void HGraph::ComputeMinusZeroChecks() {
1977 BitVector visited(GetMaximumValueID());
1978 for (int i = 0; i < blocks_.length(); ++i) {
1979 for (HInstruction* current = blocks_[i]->first();
1980 current != NULL;
1981 current = current->next()) {
1982 if (current->IsChange()) {
1983 HChange* change = HChange::cast(current);
1984 // Propagate flags for negative zero checks upwards from conversions
1985 // int32-to-tagged and int32-to-double.
1986 Representation from = change->value()->representation();
1987 ASSERT(from.Equals(change->from()));
1988 if (from.IsInteger32()) {
1989 ASSERT(change->to().IsTagged() || change->to().IsDouble());
1990 ASSERT(visited.IsEmpty());
1991 PropagateMinusZeroChecks(change->value(), &visited);
1992 visited.Clear();
1993 }
1994 }
1995 }
1996 }
1997 }
1998
1999
1987 // Implementation of utility classes to represent an expression's context in 2000 // Implementation of utility classes to represent an expression's context in
1988 // the AST. 2001 // the AST.
1989 AstContext::AstContext(HGraphBuilder* owner, Expression::Context kind) 2002 AstContext::AstContext(HGraphBuilder* owner, Expression::Context kind)
1990 : owner_(owner), kind_(kind), outer_(owner->ast_context()) { 2003 : owner_(owner), kind_(kind), outer_(owner->ast_context()) {
1991 owner->set_ast_context(this); // Push. 2004 owner->set_ast_context(this); // Push.
1992 #ifdef DEBUG 2005 #ifdef DEBUG
1993 original_length_ = owner->environment()->length(); 2006 original_length_ = owner->environment()->length();
1994 #endif 2007 #endif
1995 } 2008 }
1996 2009
(...skipping 239 matching lines...) Expand 10 before | Expand all | Expand 10 after
2236 rep.Analyze(); 2249 rep.Analyze();
2237 2250
2238 if (FLAG_use_range) { 2251 if (FLAG_use_range) {
2239 HRangeAnalysis rangeAnalysis(graph_); 2252 HRangeAnalysis rangeAnalysis(graph_);
2240 rangeAnalysis.Analyze(); 2253 rangeAnalysis.Analyze();
2241 } 2254 }
2242 2255
2243 graph_->InitializeInferredTypes(); 2256 graph_->InitializeInferredTypes();
2244 graph_->Canonicalize(); 2257 graph_->Canonicalize();
2245 graph_->InsertRepresentationChanges(); 2258 graph_->InsertRepresentationChanges();
2259 graph_->ComputeMinusZeroChecks();
2246 2260
2247 // Eliminate redundant stack checks on backwards branches. 2261 // Eliminate redundant stack checks on backwards branches.
2248 HStackCheckEliminator sce(graph_); 2262 HStackCheckEliminator sce(graph_);
2249 sce.Process(); 2263 sce.Process();
2250 2264
2251 // Perform common subexpression elimination and loop-invariant code motion. 2265 // Perform common subexpression elimination and loop-invariant code motion.
2252 if (FLAG_use_gvn) { 2266 if (FLAG_use_gvn) {
2253 HPhase phase("Global value numbering", graph_); 2267 HPhase phase("Global value numbering", graph_);
2254 HGlobalValueNumberer gvn(graph_); 2268 HGlobalValueNumberer gvn(graph_);
2255 gvn.Analyze(); 2269 gvn.Analyze();
(...skipping 673 matching lines...) Expand 10 before | Expand all | Expand 10 after
2929 global->Lookup(*var->name(), lookup); 2943 global->Lookup(*var->name(), lookup);
2930 if (!lookup->IsProperty()) { 2944 if (!lookup->IsProperty()) {
2931 BAILOUT("global variable cell not yet introduced"); 2945 BAILOUT("global variable cell not yet introduced");
2932 } 2946 }
2933 if (lookup->type() != NORMAL) { 2947 if (lookup->type() != NORMAL) {
2934 BAILOUT("global variable has accessors"); 2948 BAILOUT("global variable has accessors");
2935 } 2949 }
2936 if (is_store && lookup->IsReadOnly()) { 2950 if (is_store && lookup->IsReadOnly()) {
2937 BAILOUT("read-only global variable"); 2951 BAILOUT("read-only global variable");
2938 } 2952 }
2953 if (lookup->holder() != *global) {
2954 BAILOUT("global property on prototype of global object");
2955 }
2956 }
2957
2958
2959 HValue* HGraphBuilder::BuildContextChainWalk(Variable* var) {
2960 ASSERT(var->IsContextSlot());
2961 HInstruction* context = new HContext;
2962 AddInstruction(context);
2963 int length = graph()->info()->scope()->ContextChainLength(var->scope());
2964 while (length-- > 0) {
2965 context = new HOuterContext(context);
2966 AddInstruction(context);
2967 }
2968 return context;
2939 } 2969 }
2940 2970
2941 2971
2942 void HGraphBuilder::VisitVariableProxy(VariableProxy* expr) { 2972 void HGraphBuilder::VisitVariableProxy(VariableProxy* expr) {
2943 Variable* variable = expr->AsVariable(); 2973 Variable* variable = expr->AsVariable();
2944 if (variable == NULL) { 2974 if (variable == NULL) {
2945 BAILOUT("reference to rewritten variable"); 2975 BAILOUT("reference to rewritten variable");
2946 } else if (variable->IsStackAllocated()) { 2976 } else if (variable->IsStackAllocated()) {
2947 if (environment()->Lookup(variable)->CheckFlag(HValue::kIsArguments)) { 2977 if (environment()->Lookup(variable)->CheckFlag(HValue::kIsArguments)) {
2948 BAILOUT("unsupported context for arguments object"); 2978 BAILOUT("unsupported context for arguments object");
2949 } 2979 }
2950 ast_context()->ReturnValue(environment()->Lookup(variable)); 2980 ast_context()->ReturnValue(environment()->Lookup(variable));
2951 } else if (variable->IsContextSlot()) { 2981 } else if (variable->IsContextSlot()) {
2952 if (variable->mode() == Variable::CONST) { 2982 if (variable->mode() == Variable::CONST) {
2953 BAILOUT("reference to const context slot"); 2983 BAILOUT("reference to const context slot");
2954 } 2984 }
2955 Slot* slot = variable->AsSlot(); 2985 HValue* context = BuildContextChainWalk(variable);
2956 CompilationInfo* info = graph()->info(); 2986 int index = variable->AsSlot()->index();
2957 int context_chain_length = info->function()->scope()-> 2987 HLoadContextSlot* instr = new HLoadContextSlot(context, 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
2961 // of reading it out of context, we could just embed the value as
2962 // a constant.
2963 HLoadContextSlot* instr =
2964 new HLoadContextSlot(context_chain_length, slot->index());
2965 ast_context()->ReturnInstruction(instr, expr->id()); 2988 ast_context()->ReturnInstruction(instr, expr->id());
2966 } else if (variable->is_global()) { 2989 } else if (variable->is_global()) {
2967 LookupResult lookup; 2990 LookupResult lookup;
2968 LookupGlobalPropertyCell(variable, &lookup, false); 2991 LookupGlobalPropertyCell(variable, &lookup, false);
2969 CHECK_BAILOUT; 2992 CHECK_BAILOUT;
2970 2993
2971 Handle<GlobalObject> global(graph()->info()->global_object()); 2994 Handle<GlobalObject> global(graph()->info()->global_object());
2972 // TODO(3039103): Handle global property load through an IC call when access 2995 // TODO(3039103): Handle global property load through an IC call when access
2973 // checks are enabled. 2996 // checks are enabled.
2974 if (global->IsAccessCheckNeeded()) { 2997 if (global->IsAccessCheckNeeded()) {
(...skipping 388 matching lines...) Expand 10 before | Expand all | Expand 10 after
3363 // superclass of Assignment and CountOperation, we cannot just pass the 3386 // superclass of Assignment and CountOperation, we cannot just pass the
3364 // owning expression instead of position and ast_id separately. 3387 // owning expression instead of position and ast_id separately.
3365 void HGraphBuilder::HandleGlobalVariableAssignment(Variable* var, 3388 void HGraphBuilder::HandleGlobalVariableAssignment(Variable* var,
3366 HValue* value, 3389 HValue* value,
3367 int position, 3390 int position,
3368 int ast_id) { 3391 int ast_id) {
3369 LookupResult lookup; 3392 LookupResult lookup;
3370 LookupGlobalPropertyCell(var, &lookup, true); 3393 LookupGlobalPropertyCell(var, &lookup, true);
3371 CHECK_BAILOUT; 3394 CHECK_BAILOUT;
3372 3395
3396 bool check_hole = !lookup.IsDontDelete() || lookup.IsReadOnly();
3373 Handle<GlobalObject> global(graph()->info()->global_object()); 3397 Handle<GlobalObject> global(graph()->info()->global_object());
3374 Handle<JSGlobalPropertyCell> cell(global->GetPropertyCell(&lookup)); 3398 Handle<JSGlobalPropertyCell> cell(global->GetPropertyCell(&lookup));
3375 HInstruction* instr = new HStoreGlobal(value, cell); 3399 HInstruction* instr = new HStoreGlobal(value, cell, check_hole);
3376 instr->set_position(position); 3400 instr->set_position(position);
3377 AddInstruction(instr); 3401 AddInstruction(instr);
3378 if (instr->HasSideEffects()) AddSimulate(ast_id); 3402 if (instr->HasSideEffects()) AddSimulate(ast_id);
3379 } 3403 }
3380 3404
3381 3405
3382 void HGraphBuilder::HandleCompoundAssignment(Assignment* expr) { 3406 void HGraphBuilder::HandleCompoundAssignment(Assignment* expr) {
3383 Expression* target = expr->target(); 3407 Expression* target = expr->target();
3384 VariableProxy* proxy = target->AsVariableProxy(); 3408 VariableProxy* proxy = target->AsVariableProxy();
3385 Variable* var = proxy->AsVariable(); 3409 Variable* var = proxy->AsVariable();
3386 Property* prop = target->AsProperty(); 3410 Property* prop = target->AsProperty();
3387 ASSERT(var == NULL || prop == NULL); 3411 ASSERT(var == NULL || prop == NULL);
3388 3412
3389 // We have a second position recorded in the FullCodeGenerator to have 3413 // We have a second position recorded in the FullCodeGenerator to have
3390 // type feedback for the binary operation. 3414 // type feedback for the binary operation.
3391 BinaryOperation* operation = expr->binary_operation(); 3415 BinaryOperation* operation = expr->binary_operation();
3392 operation->RecordTypeFeedback(oracle());
3393 3416
3394 if (var != NULL) { 3417 if (var != NULL) {
3395 if (!var->is_global() && !var->IsStackAllocated()) { 3418 if (!var->is_global() && !var->IsStackAllocated()) {
3396 BAILOUT("non-stack/non-global in compound assignment"); 3419 BAILOUT("non-stack/non-global in compound assignment");
3397 } 3420 }
3398 3421
3399 VISIT_FOR_VALUE(operation); 3422 VISIT_FOR_VALUE(operation);
3400 3423
3401 if (var->is_global()) { 3424 if (var->is_global()) {
3402 HandleGlobalVariableAssignment(var, 3425 HandleGlobalVariableAssignment(var,
(...skipping 89 matching lines...) Expand 10 before | Expand all | Expand 10 after
3492 3515
3493 if (expr->is_compound()) { 3516 if (expr->is_compound()) {
3494 HandleCompoundAssignment(expr); 3517 HandleCompoundAssignment(expr);
3495 return; 3518 return;
3496 } 3519 }
3497 3520
3498 if (var != NULL) { 3521 if (var != NULL) {
3499 if (proxy->IsArguments()) BAILOUT("assignment to arguments"); 3522 if (proxy->IsArguments()) BAILOUT("assignment to arguments");
3500 3523
3501 // Handle the assignment. 3524 // Handle the assignment.
3502 if (var->is_global()) { 3525 if (var->IsStackAllocated()) {
3526 HValue* value = NULL;
3527 // Handle stack-allocated variables on the right-hand side directly.
3528 // We do not allow the arguments object to occur in a context where it
3529 // may escape, but assignments to stack-allocated locals are
3530 // permitted. Handling such assignments here bypasses the check for
3531 // the arguments object in VisitVariableProxy.
3532 Variable* rhs_var = expr->value()->AsVariableProxy()->AsVariable();
3533 if (rhs_var != NULL && rhs_var->IsStackAllocated()) {
3534 value = environment()->Lookup(rhs_var);
3535 } else {
3536 VISIT_FOR_VALUE(expr->value());
3537 value = Pop();
3538 }
3539 Bind(var, value);
3540 ast_context()->ReturnValue(value);
3541
3542 } else if (var->IsContextSlot() && var->mode() != Variable::CONST) {
3543 VISIT_FOR_VALUE(expr->value());
3544 HValue* context = BuildContextChainWalk(var);
3545 int index = var->AsSlot()->index();
3546 HStoreContextSlot* instr = new HStoreContextSlot(context, index, Top());
3547 AddInstruction(instr);
3548 if (instr->HasSideEffects()) AddSimulate(expr->AssignmentId());
3549 ast_context()->ReturnValue(Pop());
3550
3551 } else if (var->is_global()) {
3503 VISIT_FOR_VALUE(expr->value()); 3552 VISIT_FOR_VALUE(expr->value());
3504 HandleGlobalVariableAssignment(var, 3553 HandleGlobalVariableAssignment(var,
3505 Top(), 3554 Top(),
3506 expr->position(), 3555 expr->position(),
3507 expr->AssignmentId()); 3556 expr->AssignmentId());
3508 } else if (var->IsStackAllocated()) { 3557 ast_context()->ReturnValue(Pop());
3509 // We allow reference to the arguments object only in assignemtns 3558
3510 // to local variables to make sure that the arguments object does
3511 // not escape and is not modified.
3512 VariableProxy* rhs = expr->value()->AsVariableProxy();
3513 if (rhs != NULL &&
3514 rhs->var()->IsStackAllocated() &&
3515 environment()->Lookup(rhs->var())->CheckFlag(HValue::kIsArguments)) {
3516 Push(environment()->Lookup(rhs->var()));
3517 } else {
3518 VISIT_FOR_VALUE(expr->value());
3519 }
3520 Bind(proxy->var(), Top());
3521 } else { 3559 } else {
3522 BAILOUT("Assigning to no non-stack-allocated/non-global variable"); 3560 BAILOUT("assignment to LOOKUP or const CONTEXT variable");
3523 } 3561 }
3524 // Return the value.
3525 ast_context()->ReturnValue(Pop());
3526 3562
3527 } else if (prop != NULL) { 3563 } else if (prop != NULL) {
3528 HandlePropertyAssignment(expr); 3564 HandlePropertyAssignment(expr);
3529 } else { 3565 } else {
3530 BAILOUT("unsupported invalid lhs"); 3566 BAILOUT("invalid left-hand side in assignment");
3531 } 3567 }
3532 } 3568 }
3533 3569
3534 3570
3535 void HGraphBuilder::VisitThrow(Throw* expr) { 3571 void HGraphBuilder::VisitThrow(Throw* expr) {
3536 // We don't optimize functions with invalid left-hand sides in 3572 // We don't optimize functions with invalid left-hand sides in
3537 // assignments, count operations, or for-in. Consequently throw can 3573 // assignments, count operations, or for-in. Consequently throw can
3538 // currently only occur in an effect context. 3574 // currently only occur in an effect context.
3539 ASSERT(ast_context()->IsEffect()); 3575 ASSERT(ast_context()->IsEffect());
3540 VISIT_FOR_VALUE(expr->exception()); 3576 VISIT_FOR_VALUE(expr->exception());
3541 3577
3542 HValue* value = environment()->Pop(); 3578 HValue* value = environment()->Pop();
3543 HControlInstruction* instr = new HThrow(value); 3579 HThrow* instr = new HThrow(value);
3544 instr->set_position(expr->position()); 3580 instr->set_position(expr->position());
3545 current_subgraph_->FinishExit(instr); 3581 AddInstruction(instr);
3582 AddSimulate(expr->id());
3583 current_subgraph_->FinishExit(new HAbnormalExit);
3546 } 3584 }
3547 3585
3548 3586
3549 void HGraphBuilder::HandlePolymorphicLoadNamedField(Property* expr, 3587 void HGraphBuilder::HandlePolymorphicLoadNamedField(Property* expr,
3550 HValue* object, 3588 HValue* object,
3551 ZoneMapList* types, 3589 ZoneMapList* types,
3552 Handle<String> name) { 3590 Handle<String> name) {
3553 int number_of_types = Min(types->length(), kMaxLoadPolymorphism); 3591 int number_of_types = Min(types->length(), kMaxLoadPolymorphism);
3554 ZoneMapList maps(number_of_types); 3592 ZoneMapList maps(number_of_types);
3555 ZoneList<HSubgraph*> subgraphs(number_of_types + 1); 3593 ZoneList<HSubgraph*> subgraphs(number_of_types + 1);
(...skipping 841 matching lines...) Expand 10 before | Expand all | Expand 10 after
4397 // access check is not enabled we assume that the function will not change 4435 // access check is not enabled we assume that the function will not change
4398 // and generate optimized code for calling the function. 4436 // and generate optimized code for calling the function.
4399 CompilationInfo* info = graph()->info(); 4437 CompilationInfo* info = graph()->info();
4400 bool known_global_function = info->has_global_object() && 4438 bool known_global_function = info->has_global_object() &&
4401 !info->global_object()->IsAccessCheckNeeded() && 4439 !info->global_object()->IsAccessCheckNeeded() &&
4402 expr->ComputeGlobalTarget(Handle<GlobalObject>(info->global_object()), 4440 expr->ComputeGlobalTarget(Handle<GlobalObject>(info->global_object()),
4403 var->name()); 4441 var->name());
4404 if (known_global_function) { 4442 if (known_global_function) {
4405 // Push the global object instead of the global receiver because 4443 // Push the global object instead of the global receiver because
4406 // code generated by the full code generator expects it. 4444 // code generated by the full code generator expects it.
4407 PushAndAdd(new HGlobalObject); 4445 HContext* context = new HContext;
4446 HGlobalObject* global_object = new HGlobalObject(context);
4447 AddInstruction(context);
4448 PushAndAdd(global_object);
4408 VisitArgumentList(expr->arguments()); 4449 VisitArgumentList(expr->arguments());
4409 CHECK_BAILOUT; 4450 CHECK_BAILOUT;
4410 4451
4411 VISIT_FOR_VALUE(expr->expression()); 4452 VISIT_FOR_VALUE(expr->expression());
4412 HValue* function = Pop(); 4453 HValue* function = Pop();
4413 AddInstruction(new HCheckFunction(function, expr->target())); 4454 AddInstruction(new HCheckFunction(function, expr->target()));
4414 4455
4415 // Replace the global object with the global receiver. 4456 // Replace the global object with the global receiver.
4416 HGlobalReceiver* global_receiver = new HGlobalReceiver; 4457 HGlobalReceiver* global_receiver = new HGlobalReceiver(global_object);
4417 // Index of the receiver from the top of the expression stack. 4458 // Index of the receiver from the top of the expression stack.
4418 const int receiver_index = argument_count - 1; 4459 const int receiver_index = argument_count - 1;
4419 AddInstruction(global_receiver); 4460 AddInstruction(global_receiver);
4420 ASSERT(environment()->ExpressionStackAt(receiver_index)-> 4461 ASSERT(environment()->ExpressionStackAt(receiver_index)->
4421 IsGlobalObject()); 4462 IsGlobalObject());
4422 environment()->SetExpressionStackAt(receiver_index, global_receiver); 4463 environment()->SetExpressionStackAt(receiver_index, global_receiver);
4423 4464
4424 if (TryInline(expr)) { 4465 if (TryInline(expr)) {
4425 if (subgraph()->HasExit()) { 4466 if (subgraph()->HasExit()) {
4426 HValue* return_value = Pop(); 4467 HValue* return_value = Pop();
4427 // If we inlined a function in a test context then we need to 4468 // If we inlined a function in a test context then we need to
4428 // emit a simulate here to shadow the ones at the end of the 4469 // emit a simulate here to shadow the ones at the end of the
4429 // predecessor blocks. Those environments contain the return 4470 // predecessor blocks. Those environments contain the return
4430 // value on top and do not correspond to any actual state of the 4471 // value on top and do not correspond to any actual state of the
4431 // unoptimized code. 4472 // unoptimized code.
4432 if (ast_context()->IsEffect()) AddSimulate(expr->id()); 4473 if (ast_context()->IsEffect()) AddSimulate(expr->id());
4433 ast_context()->ReturnValue(return_value); 4474 ast_context()->ReturnValue(return_value);
4434 } 4475 }
4435 return; 4476 return;
4436 } 4477 }
4437 // Check for bailout, as trying to inline might fail due to bailout 4478 // Check for bailout, as trying to inline might fail due to bailout
4438 // during hydrogen processing. 4479 // during hydrogen processing.
4439 CHECK_BAILOUT; 4480 CHECK_BAILOUT;
4440 4481
4441 call = new HCallKnownGlobal(expr->target(), argument_count); 4482 call = new HCallKnownGlobal(expr->target(), argument_count);
4442 } else { 4483 } else {
4443 PushAndAdd(new HGlobalObject); 4484 HContext* context = new HContext;
4485 AddInstruction(context);
4486 PushAndAdd(new HGlobalObject(context));
4444 VisitArgumentList(expr->arguments()); 4487 VisitArgumentList(expr->arguments());
4445 CHECK_BAILOUT; 4488 CHECK_BAILOUT;
4446 4489
4447 call = new HCallGlobal(var->name(), argument_count); 4490 call = new HCallGlobal(var->name(), argument_count);
4448 } 4491 }
4449 4492
4450 } else { 4493 } else {
4451 PushAndAdd(new HGlobalReceiver); 4494 HContext* context = new HContext;
4495 HGlobalObject* global_object = new HGlobalObject(context);
4496 AddInstruction(context);
4497 AddInstruction(global_object);
4498 PushAndAdd(new HGlobalReceiver(global_object));
4452 VisitArgumentList(expr->arguments()); 4499 VisitArgumentList(expr->arguments());
4453 CHECK_BAILOUT; 4500 CHECK_BAILOUT;
4454 4501
4455 call = new HCallFunction(argument_count); 4502 call = new HCallFunction(argument_count);
4456 } 4503 }
4457 } 4504 }
4458 4505
4459 call->set_position(expr->position()); 4506 call->set_position(expr->position());
4460 ProcessCall(call); 4507 ProcessCall(call);
4461 ast_context()->ReturnInstruction(call, expr->id()); 4508 ast_context()->ReturnInstruction(call, expr->id());
(...skipping 344 matching lines...) Expand 10 before | Expand all | Expand 10 after
4806 break; 4853 break;
4807 case Token::SHR: 4854 case Token::SHR:
4808 instr = new HShr(left, right); 4855 instr = new HShr(left, right);
4809 break; 4856 break;
4810 case Token::SHL: 4857 case Token::SHL:
4811 instr = new HShl(left, right); 4858 instr = new HShl(left, right);
4812 break; 4859 break;
4813 default: 4860 default:
4814 UNREACHABLE(); 4861 UNREACHABLE();
4815 } 4862 }
4816 TypeInfo info = oracle()->BinaryType(expr, TypeFeedbackOracle::RESULT); 4863 TypeInfo info = oracle()->BinaryType(expr);
4817 // If we hit an uninitialized binary op stub we will get type info 4864 // If we hit an uninitialized binary op stub we will get type info
4818 // for a smi operation. If one of the operands is a constant string 4865 // for a smi operation. If one of the operands is a constant string
4819 // do not generate code assuming it is a smi operation. 4866 // do not generate code assuming it is a smi operation.
4820 if (info.IsSmi() && 4867 if (info.IsSmi() &&
4821 ((left->IsConstant() && HConstant::cast(left)->HasStringValue()) || 4868 ((left->IsConstant() && HConstant::cast(left)->HasStringValue()) ||
4822 (right->IsConstant() && HConstant::cast(right)->HasStringValue()))) { 4869 (right->IsConstant() && HConstant::cast(right)->HasStringValue()))) {
4823 return instr; 4870 return instr;
4824 } 4871 }
4825 if (FLAG_trace_representation) { 4872 if (FLAG_trace_representation) {
4826 PrintF("Info: %s/%s\n", info.ToString(), ToRepresentation(info).Mnemonic()); 4873 PrintF("Info: %s/%s\n", info.ToString(), ToRepresentation(info).Mnemonic());
(...skipping 130 matching lines...) Expand 10 before | Expand all | Expand 10 after
4957 return; 5004 return;
4958 } 5005 }
4959 5006
4960 VISIT_FOR_VALUE(expr->left()); 5007 VISIT_FOR_VALUE(expr->left());
4961 VISIT_FOR_VALUE(expr->right()); 5008 VISIT_FOR_VALUE(expr->right());
4962 5009
4963 HValue* right = Pop(); 5010 HValue* right = Pop();
4964 HValue* left = Pop(); 5011 HValue* left = Pop();
4965 Token::Value op = expr->op(); 5012 Token::Value op = expr->op();
4966 5013
4967 TypeInfo info = oracle()->CompareType(expr, TypeFeedbackOracle::RESULT); 5014 TypeInfo info = oracle()->CompareType(expr);
4968 HInstruction* instr = NULL; 5015 HInstruction* instr = NULL;
4969 if (op == Token::INSTANCEOF) { 5016 if (op == Token::INSTANCEOF) {
4970 // Check to see if the rhs of the instanceof is a global function not 5017 // Check to see if the rhs of the instanceof is a global function not
4971 // residing in new space. If it is we assume that the function will stay the 5018 // residing in new space. If it is we assume that the function will stay the
4972 // same. 5019 // same.
4973 Handle<JSFunction> target = Handle<JSFunction>::null(); 5020 Handle<JSFunction> target = Handle<JSFunction>::null();
4974 Variable* var = expr->right()->AsVariableProxy()->AsVariable(); 5021 Variable* var = expr->right()->AsVariableProxy()->AsVariable();
4975 bool global_function = (var != NULL) && var->is_global() && !var->is_this(); 5022 bool global_function = (var != NULL) && var->is_global() && !var->is_this();
4976 CompilationInfo* info = graph()->info(); 5023 CompilationInfo* info = graph()->info();
4977 if (global_function && 5024 if (global_function &&
(...skipping 154 matching lines...) Expand 10 before | Expand all | Expand 10 after
5132 } 5179 }
5133 5180
5134 5181
5135 void HGraphBuilder::GenerateIsStringWrapperSafeForDefaultValueOf( 5182 void HGraphBuilder::GenerateIsStringWrapperSafeForDefaultValueOf(
5136 int argument_count, 5183 int argument_count,
5137 int ast_id) { 5184 int ast_id) {
5138 BAILOUT("inlined runtime function: IsStringWrapperSafeForDefaultValueOf"); 5185 BAILOUT("inlined runtime function: IsStringWrapperSafeForDefaultValueOf");
5139 } 5186 }
5140 5187
5141 5188
5142 // Support for construct call checks. 5189 // Support for construct call checks.
5143 void HGraphBuilder::GenerateIsConstructCall(int argument_count, int ast_id) { 5190 void HGraphBuilder::GenerateIsConstructCall(int argument_count, int ast_id) {
5144 BAILOUT("inlined runtime function: IsConstructCall"); 5191 ASSERT(argument_count == 0);
5192 ast_context()->ReturnInstruction(new HIsConstructCall, ast_id);
5145 } 5193 }
5146 5194
5147 5195
5148 // Support for arguments.length and arguments[?]. 5196 // Support for arguments.length and arguments[?].
5149 void HGraphBuilder::GenerateArgumentsLength(int argument_count, int ast_id) { 5197 void HGraphBuilder::GenerateArgumentsLength(int argument_count, int ast_id) {
5150 ASSERT(argument_count == 0); 5198 ASSERT(argument_count == 0);
5151 HInstruction* elements = AddInstruction(new HArgumentsElements); 5199 HInstruction* elements = AddInstruction(new HArgumentsElements);
5152 HArgumentsLength* result = new HArgumentsLength(elements); 5200 HArgumentsLength* result = new HArgumentsLength(elements);
5153 ast_context()->ReturnInstruction(result, ast_id); 5201 ast_context()->ReturnInstruction(result, ast_id);
5154 } 5202 }
(...skipping 723 matching lines...) Expand 10 before | Expand all | Expand 10 after
5878 } 5926 }
5879 } 5927 }
5880 5928
5881 #ifdef DEBUG 5929 #ifdef DEBUG
5882 if (graph_ != NULL) graph_->Verify(); 5930 if (graph_ != NULL) graph_->Verify();
5883 if (allocator_ != NULL) allocator_->Verify(); 5931 if (allocator_ != NULL) allocator_->Verify();
5884 #endif 5932 #endif
5885 } 5933 }
5886 5934
5887 } } // namespace v8::internal 5935 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « src/hydrogen.h ('k') | src/hydrogen-instructions.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698