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

Side by Side Diff: src/hydrogen.cc

Issue 6711027: [Isolates] Merge 7201:7258 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
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 96 matching lines...) Expand 10 before | Expand all | Expand 10 after
107 if (first_ == NULL) { 107 if (first_ == NULL) {
108 HBlockEntry* entry = new HBlockEntry(); 108 HBlockEntry* entry = new HBlockEntry();
109 entry->InitializeAsFirst(this); 109 entry->InitializeAsFirst(this);
110 first_ = last_ = entry; 110 first_ = last_ = entry;
111 } 111 }
112 instr->InsertAfter(last_); 112 instr->InsertAfter(last_);
113 last_ = instr; 113 last_ = instr;
114 } 114 }
115 115
116 116
117 HDeoptimize* HBasicBlock::CreateDeoptimize() {
118 ASSERT(HasEnvironment());
119 HEnvironment* environment = last_environment();
120
121 HDeoptimize* instr = new HDeoptimize(environment->length());
122
123 for (int i = 0; i < environment->length(); i++) {
124 HValue* val = environment->values()->at(i);
125 instr->AddEnvironmentValue(val);
126 }
127
128 return instr;
129 }
130
131
117 HSimulate* HBasicBlock::CreateSimulate(int id) { 132 HSimulate* HBasicBlock::CreateSimulate(int id) {
118 ASSERT(HasEnvironment()); 133 ASSERT(HasEnvironment());
119 HEnvironment* environment = last_environment(); 134 HEnvironment* environment = last_environment();
120 ASSERT(id == AstNode::kNoNumber || 135 ASSERT(id == AstNode::kNoNumber ||
121 environment->closure()->shared()->VerifyBailoutId(id)); 136 environment->closure()->shared()->VerifyBailoutId(id));
122 137
123 int push_count = environment->push_count(); 138 int push_count = environment->push_count();
124 int pop_count = environment->pop_count(); 139 int pop_count = environment->pop_count();
125 140
126 int length = environment->length(); 141 int length = environment->length();
(...skipping 2339 matching lines...) Expand 10 before | Expand all | Expand 10 after
2466 // We only optimize switch statements with smi-literal smi comparisons, 2481 // We only optimize switch statements with smi-literal smi comparisons,
2467 // with a bounded number of clauses. 2482 // with a bounded number of clauses.
2468 const int kCaseClauseLimit = 128; 2483 const int kCaseClauseLimit = 128;
2469 ZoneList<CaseClause*>* clauses = stmt->cases(); 2484 ZoneList<CaseClause*>* clauses = stmt->cases();
2470 int clause_count = clauses->length(); 2485 int clause_count = clauses->length();
2471 if (clause_count > kCaseClauseLimit) { 2486 if (clause_count > kCaseClauseLimit) {
2472 BAILOUT("SwitchStatement: too many clauses"); 2487 BAILOUT("SwitchStatement: too many clauses");
2473 } 2488 }
2474 2489
2475 VISIT_FOR_VALUE(stmt->tag()); 2490 VISIT_FOR_VALUE(stmt->tag());
2491 AddSimulate(stmt->EntryId());
2476 HValue* tag_value = Pop(); 2492 HValue* tag_value = Pop();
2477 HBasicBlock* first_test_block = current_block(); 2493 HBasicBlock* first_test_block = current_block();
2478 2494
2479 // 1. Build all the tests, with dangling true branches. Unconditionally 2495 // 1. Build all the tests, with dangling true branches. Unconditionally
2480 // deoptimize if we encounter a non-smi comparison. 2496 // deoptimize if we encounter a non-smi comparison.
2481 for (int i = 0; i < clause_count; ++i) { 2497 for (int i = 0; i < clause_count; ++i) {
2482 CaseClause* clause = clauses->at(i); 2498 CaseClause* clause = clauses->at(i);
2483 if (clause->is_default()) continue; 2499 if (clause->is_default()) continue;
2484 if (!clause->label()->IsSmiLiteral()) { 2500 if (!clause->label()->IsSmiLiteral()) {
2485 BAILOUT("SwitchStatement: non-literal switch label"); 2501 BAILOUT("SwitchStatement: non-literal switch label");
2486 } 2502 }
2487 2503
2488 // Unconditionally deoptimize on the first non-smi compare. 2504 // Unconditionally deoptimize on the first non-smi compare.
2489 clause->RecordTypeFeedback(oracle()); 2505 clause->RecordTypeFeedback(oracle());
2490 if (!clause->IsSmiCompare()) { 2506 if (!clause->IsSmiCompare()) {
2491 if (current_block() == first_test_block) { 2507 current_block()->FinishExitWithDeoptimization();
2492 // If the first test is the one that deopts and if the tag value is
2493 // a phi, we need to have some use of that phi to prevent phi
2494 // elimination from removing it. This HSimulate is such a use.
2495 Push(tag_value);
2496 AddSimulate(stmt->EntryId());
2497 Drop(1);
2498 }
2499 current_block()->Finish(new HDeoptimize());
2500 set_current_block(NULL); 2508 set_current_block(NULL);
2501 break; 2509 break;
2502 } 2510 }
2503 2511
2504 // Otherwise generate a compare and branch. 2512 // Otherwise generate a compare and branch.
2505 VISIT_FOR_VALUE(clause->label()); 2513 VISIT_FOR_VALUE(clause->label());
2506 HValue* label_value = Pop(); 2514 HValue* label_value = Pop();
2507 HCompare* compare = new HCompare(tag_value, label_value, Token::EQ_STRICT); 2515 HCompare* compare = new HCompare(tag_value, label_value, Token::EQ_STRICT);
2508 compare->SetInputRepresentation(Representation::Integer32()); 2516 compare->SetInputRepresentation(Representation::Integer32());
2509 ASSERT(!compare->HasSideEffects()); 2517 ASSERT(!compare->HasSideEffects());
(...skipping 599 matching lines...) Expand 10 before | Expand all | Expand 10 after
3109 current_block()->Goto(join); 3117 current_block()->Goto(join);
3110 3118
3111 set_current_block(if_false); 3119 set_current_block(if_false);
3112 } 3120 }
3113 } 3121 }
3114 3122
3115 // Finish up. Unconditionally deoptimize if we've handled all the maps we 3123 // Finish up. Unconditionally deoptimize if we've handled all the maps we
3116 // know about and do not want to handle ones we've never seen. Otherwise 3124 // know about and do not want to handle ones we've never seen. Otherwise
3117 // use a generic IC. 3125 // use a generic IC.
3118 if (count == types->length() && FLAG_deoptimize_uncommon_cases) { 3126 if (count == types->length() && FLAG_deoptimize_uncommon_cases) {
3119 current_block()->FinishExit(new HDeoptimize); 3127 current_block()->FinishExitWithDeoptimization();
3120 } else { 3128 } else {
3121 HInstruction* instr = BuildStoreNamedGeneric(object, name, value); 3129 HInstruction* instr = BuildStoreNamedGeneric(object, name, value);
3122 instr->set_position(expr->position()); 3130 instr->set_position(expr->position());
3123 AddInstruction(instr); 3131 AddInstruction(instr);
3124 3132
3125 if (join != NULL) { 3133 if (join != NULL) {
3126 if (!ast_context()->IsEffect()) Push(value); 3134 if (!ast_context()->IsEffect()) Push(value);
3127 current_block()->Goto(join); 3135 current_block()->Goto(join);
3128 } else { 3136 } else {
3129 // The HSimulate for the store should not see the stored value in 3137 // The HSimulate for the store should not see the stored value in
(...skipping 327 matching lines...) Expand 10 before | Expand all | Expand 10 after
3457 current_block()->Goto(join); 3465 current_block()->Goto(join);
3458 3466
3459 set_current_block(if_false); 3467 set_current_block(if_false);
3460 } 3468 }
3461 } 3469 }
3462 3470
3463 // Finish up. Unconditionally deoptimize if we've handled all the maps we 3471 // Finish up. Unconditionally deoptimize if we've handled all the maps we
3464 // know about and do not want to handle ones we've never seen. Otherwise 3472 // know about and do not want to handle ones we've never seen. Otherwise
3465 // use a generic IC. 3473 // use a generic IC.
3466 if (count == types->length() && FLAG_deoptimize_uncommon_cases) { 3474 if (count == types->length() && FLAG_deoptimize_uncommon_cases) {
3467 current_block()->FinishExit(new HDeoptimize); 3475 current_block()->FinishExitWithDeoptimization();
3468 } else { 3476 } else {
3469 HInstruction* instr = BuildLoadNamedGeneric(object, expr); 3477 HInstruction* instr = BuildLoadNamedGeneric(object, expr);
3470 instr->set_position(expr->position()); 3478 instr->set_position(expr->position());
3471 3479
3472 if (join != NULL) { 3480 if (join != NULL) {
3473 AddInstruction(instr); 3481 AddInstruction(instr);
3474 if (!ast_context()->IsEffect()) Push(instr); 3482 if (!ast_context()->IsEffect()) Push(instr);
3475 current_block()->Goto(join); 3483 current_block()->Goto(join);
3476 } else { 3484 } else {
3477 ast_context()->ReturnInstruction(instr, expr->id()); 3485 ast_context()->ReturnInstruction(instr, expr->id());
(...skipping 344 matching lines...) Expand 10 before | Expand all | Expand 10 after
3822 3830
3823 if (current_block() != NULL) current_block()->Goto(join); 3831 if (current_block() != NULL) current_block()->Goto(join);
3824 set_current_block(if_false); 3832 set_current_block(if_false);
3825 } 3833 }
3826 } 3834 }
3827 3835
3828 // Finish up. Unconditionally deoptimize if we've handled all the maps we 3836 // Finish up. Unconditionally deoptimize if we've handled all the maps we
3829 // know about and do not want to handle ones we've never seen. Otherwise 3837 // know about and do not want to handle ones we've never seen. Otherwise
3830 // use a generic IC. 3838 // use a generic IC.
3831 if (count == types->length() && FLAG_deoptimize_uncommon_cases) { 3839 if (count == types->length() && FLAG_deoptimize_uncommon_cases) {
3832 current_block()->FinishExit(new HDeoptimize); 3840 current_block()->FinishExitWithDeoptimization();
3833 } else { 3841 } else {
3834 HContext* context = new HContext; 3842 HContext* context = new HContext;
3835 AddInstruction(context); 3843 AddInstruction(context);
3836 HCallNamed* call = new HCallNamed(context, name, argument_count); 3844 HCallNamed* call = new HCallNamed(context, name, argument_count);
3837 call->set_position(expr->position()); 3845 call->set_position(expr->position());
3838 PreProcessCall(call); 3846 PreProcessCall(call);
3839 3847
3840 if (join != NULL) { 3848 if (join != NULL) {
3841 AddInstruction(call); 3849 AddInstruction(call);
3842 if (!ast_context()->IsEffect()) Push(call); 3850 if (!ast_context()->IsEffect()) Push(call);
(...skipping 367 matching lines...) Expand 10 before | Expand all | Expand 10 after
4210 expr->GetReceiverTypes()->first(), 4218 expr->GetReceiverTypes()->first(),
4211 true); 4219 true);
4212 HInstruction* result = 4220 HInstruction* result =
4213 new HApplyArguments(function, receiver, length, elements); 4221 new HApplyArguments(function, receiver, length, elements);
4214 result->set_position(expr->position()); 4222 result->set_position(expr->position());
4215 ast_context()->ReturnInstruction(result, expr->id()); 4223 ast_context()->ReturnInstruction(result, expr->id());
4216 return true; 4224 return true;
4217 } 4225 }
4218 4226
4219 4227
4220 static bool HasCustomCallGenerator(Handle<JSFunction> function) {
4221 SharedFunctionInfo* info = function->shared();
4222 return info->HasBuiltinFunctionId() &&
4223 CallStubCompiler::HasCustomCallGenerator(info->builtin_function_id());
4224 }
4225
4226
4227 void HGraphBuilder::VisitCall(Call* expr) { 4228 void HGraphBuilder::VisitCall(Call* expr) {
4228 Expression* callee = expr->expression(); 4229 Expression* callee = expr->expression();
4229 int argument_count = expr->arguments()->length() + 1; // Plus receiver. 4230 int argument_count = expr->arguments()->length() + 1; // Plus receiver.
4230 HInstruction* call = NULL; 4231 HInstruction* call = NULL;
4231 4232
4232 Property* prop = callee->AsProperty(); 4233 Property* prop = callee->AsProperty();
4233 if (prop != NULL) { 4234 if (prop != NULL) {
4234 if (!prop->key()->IsPropertyName()) { 4235 if (!prop->key()->IsPropertyName()) {
4235 // Keyed function call. 4236 // Keyed function call.
4236 VISIT_FOR_VALUE(prop->obj()); 4237 VISIT_FOR_VALUE(prop->obj());
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after
4274 if (expr->IsMonomorphic()) { 4275 if (expr->IsMonomorphic()) {
4275 Handle<Map> receiver_map = 4276 Handle<Map> receiver_map =
4276 (types == NULL) ? Handle<Map>::null() : types->first(); 4277 (types == NULL) ? Handle<Map>::null() : types->first();
4277 if (TryInlineBuiltinFunction(expr, 4278 if (TryInlineBuiltinFunction(expr,
4278 receiver, 4279 receiver,
4279 receiver_map, 4280 receiver_map,
4280 expr->check_type())) { 4281 expr->check_type())) {
4281 return; 4282 return;
4282 } 4283 }
4283 4284
4284 if (HasCustomCallGenerator(expr->target()) || 4285 if (CallStubCompiler::HasCustomCallGenerator(*expr->target()) ||
4285 CallOptimization(*expr->target()).is_simple_api_call() ||
4286 expr->check_type() != RECEIVER_MAP_CHECK) { 4286 expr->check_type() != RECEIVER_MAP_CHECK) {
4287 // When the target has a custom call IC generator, use the IC, 4287 // When the target has a custom call IC generator, use the IC,
4288 // because it is likely to generate better code. Similarly, we 4288 // because it is likely to generate better code. Also use the IC
4289 // generate better call stubs for some API functions. 4289 // when a primitive receiver check is required.
4290 // Also use the IC when a primitive receiver check is required.
4291 HContext* context = new HContext; 4290 HContext* context = new HContext;
4292 AddInstruction(context); 4291 AddInstruction(context);
4293 call = PreProcessCall(new HCallNamed(context, name, argument_count)); 4292 call = PreProcessCall(new HCallNamed(context, name, argument_count));
4294 } else { 4293 } else {
4295 AddCheckConstantFunction(expr, receiver, receiver_map, true); 4294 AddCheckConstantFunction(expr, receiver, receiver_map, true);
4296 4295
4297 if (TryInline(expr)) { 4296 if (TryInline(expr)) {
4298 return; 4297 return;
4299 } else { 4298 } else {
4300 // Check for bailout, as the TryInline call in the if condition above 4299 // Check for bailout, as the TryInline call in the if condition above
(...skipping 226 matching lines...) Expand 10 before | Expand all | Expand 10 after
4527 4526
4528 HBasicBlock* join = 4527 HBasicBlock* join =
4529 CreateJoin(materialize_false, materialize_true, expr->id()); 4528 CreateJoin(materialize_false, materialize_true, expr->id());
4530 set_current_block(join); 4529 set_current_block(join);
4531 ast_context()->ReturnValue(Pop()); 4530 ast_context()->ReturnValue(Pop());
4532 } else { 4531 } else {
4533 ASSERT(ast_context()->IsEffect()); 4532 ASSERT(ast_context()->IsEffect());
4534 VisitForEffect(expr->expression()); 4533 VisitForEffect(expr->expression());
4535 } 4534 }
4536 4535
4537 } else if (op == Token::BIT_NOT || op == Token::SUB) { 4536 } else if (op == Token::TYPEOF) {
4537 VISIT_FOR_VALUE(expr->expression());
4538 HValue* value = Pop();
4539 ast_context()->ReturnInstruction(new HTypeof(value), expr->id());
4540
4541 } else {
4538 VISIT_FOR_VALUE(expr->expression()); 4542 VISIT_FOR_VALUE(expr->expression());
4539 HValue* value = Pop(); 4543 HValue* value = Pop();
4540 HInstruction* instr = NULL; 4544 HInstruction* instr = NULL;
4541 switch (op) { 4545 switch (op) {
4542 case Token::BIT_NOT: 4546 case Token::BIT_NOT:
4543 instr = new HBitNot(value); 4547 instr = new HBitNot(value);
4544 break; 4548 break;
4545 case Token::SUB: 4549 case Token::SUB:
4546 instr = new HMul(graph_->GetConstantMinus1(), value); 4550 instr = new HMul(value, graph_->GetConstantMinus1());
4551 break;
4552 case Token::ADD:
4553 instr = new HMul(value, graph_->GetConstant1());
4547 break; 4554 break;
4548 default: 4555 default:
4549 UNREACHABLE(); 4556 BAILOUT("Value: unsupported unary operation");
4550 break; 4557 break;
4551 } 4558 }
4552 ast_context()->ReturnInstruction(instr, expr->id()); 4559 ast_context()->ReturnInstruction(instr, expr->id());
4553 } else if (op == Token::TYPEOF) {
4554 VISIT_FOR_VALUE(expr->expression());
4555 HValue* value = Pop();
4556 ast_context()->ReturnInstruction(new HTypeof(value), expr->id());
4557 } else {
4558 BAILOUT("Value: unsupported unary operation");
4559 } 4560 }
4560 } 4561 }
4561 4562
4562 4563
4563 void HGraphBuilder::VisitIncrementOperation(IncrementOperation* expr) { 4564 void HGraphBuilder::VisitIncrementOperation(IncrementOperation* expr) {
4564 // IncrementOperation is never visited by the visitor. It only 4565 // IncrementOperation is never visited by the visitor. It only
4565 // occurs as a subexpression of CountOperation. 4566 // occurs as a subexpression of CountOperation.
4566 UNREACHABLE(); 4567 UNREACHABLE();
4567 } 4568 }
4568 4569
(...skipping 1357 matching lines...) Expand 10 before | Expand all | Expand 10 after
5926 } 5927 }
5927 } 5928 }
5928 5929
5929 #ifdef DEBUG 5930 #ifdef DEBUG
5930 if (graph_ != NULL) graph_->Verify(); 5931 if (graph_ != NULL) graph_->Verify();
5931 if (allocator_ != NULL) allocator_->Verify(); 5932 if (allocator_ != NULL) allocator_->Verify();
5932 #endif 5933 #endif
5933 } 5934 }
5934 5935
5935 } } // namespace v8::internal 5936 } } // namespace v8::internal
OLDNEW
« src/global-handles.cc ('K') | « src/hydrogen.h ('k') | src/hydrogen-instructions.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698