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

Side by Side Diff: src/hydrogen.cc

Issue 6538080: Add template parameter for hydrogen input operands. (Closed) Base URL: http://v8.googlecode.com/svn/branches/bleeding_edge/
Patch Set: added other platforms 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 | « 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 2240 matching lines...) Expand 10 before | Expand all | Expand 10 after
2251 current_block()->AddPhi(instr); 2251 current_block()->AddPhi(instr);
2252 } 2252 }
2253 2253
2254 2254
2255 void HGraphBuilder::PushAndAdd(HInstruction* instr) { 2255 void HGraphBuilder::PushAndAdd(HInstruction* instr) {
2256 Push(instr); 2256 Push(instr);
2257 AddInstruction(instr); 2257 AddInstruction(instr);
2258 } 2258 }
2259 2259
2260 2260
2261 void HGraphBuilder::PreProcessCall(HCall* call) { 2261 template <int V>
2262 HInstruction* HGraphBuilder::PreProcessCall(HCall<V>* call) {
2262 int count = call->argument_count(); 2263 int count = call->argument_count();
2263 ZoneList<HValue*> arguments(count); 2264 ZoneList<HValue*> arguments(count);
2264 for (int i = 0; i < count; ++i) { 2265 for (int i = 0; i < count; ++i) {
2265 arguments.Add(Pop()); 2266 arguments.Add(Pop());
2266 } 2267 }
2267 2268
2268 while (!arguments.is_empty()) { 2269 while (!arguments.is_empty()) {
2269 AddInstruction(new HPushArgument(arguments.RemoveLast())); 2270 AddInstruction(new HPushArgument(arguments.RemoveLast()));
2270 } 2271 }
2272 return call;
2271 } 2273 }
2272 2274
2273 2275
2274 void HGraphBuilder::SetupScope(Scope* scope) { 2276 void HGraphBuilder::SetupScope(Scope* scope) {
2275 // We don't yet handle the function name for named function expressions. 2277 // We don't yet handle the function name for named function expressions.
2276 if (scope->function() != NULL) BAILOUT("named function expression"); 2278 if (scope->function() != NULL) BAILOUT("named function expression");
2277 2279
2278 // We can't handle heap-allocated locals. 2280 // We can't handle heap-allocated locals.
2279 if (scope->num_heap_slots() > 0) BAILOUT("heap allocated locals"); 2281 if (scope->num_heap_slots() > 0) BAILOUT("heap allocated locals");
2280 2282
(...skipping 1662 matching lines...) Expand 10 before | Expand all | Expand 10 after
3943 SubgraphScope scope(this, subgraph); 3945 SubgraphScope scope(this, subgraph);
3944 AddCheckConstantFunction(expr, receiver, map, false); 3946 AddCheckConstantFunction(expr, receiver, map, false);
3945 if (FLAG_trace_inlining && FLAG_polymorphic_inlining) { 3947 if (FLAG_trace_inlining && FLAG_polymorphic_inlining) {
3946 PrintF("Trying to inline the polymorphic call to %s\n", 3948 PrintF("Trying to inline the polymorphic call to %s\n",
3947 *name->ToCString()); 3949 *name->ToCString());
3948 } 3950 }
3949 if (!FLAG_polymorphic_inlining || !TryInline(expr)) { 3951 if (!FLAG_polymorphic_inlining || !TryInline(expr)) {
3950 // Check for bailout, as trying to inline might fail due to bailout 3952 // Check for bailout, as trying to inline might fail due to bailout
3951 // during hydrogen processing. 3953 // during hydrogen processing.
3952 CHECK_BAILOUT; 3954 CHECK_BAILOUT;
3953 HCall* call = new HCallConstantFunction(expr->target(), argument_count); 3955 HCallConstantFunction* call =
3956 new HCallConstantFunction(expr->target(), argument_count);
3954 call->set_position(expr->position()); 3957 call->set_position(expr->position());
3955 PreProcessCall(call); 3958 PreProcessCall(call);
3956 PushAndAdd(call); 3959 PushAndAdd(call);
3957 } 3960 }
3958 maps.Add(map); 3961 maps.Add(map);
3959 subgraphs.Add(subgraph); 3962 subgraphs.Add(subgraph);
3960 } else { 3963 } else {
3961 needs_generic = true; 3964 needs_generic = true;
3962 } 3965 }
3963 } 3966 }
3964 3967
3965 // If we couldn't compute the target for any of the maps just perform an 3968 // If we couldn't compute the target for any of the maps just perform an
3966 // IC call. 3969 // IC call.
3967 if (maps.length() == 0) { 3970 if (maps.length() == 0) {
3968 HContext* context = new HContext; 3971 HContext* context = new HContext;
3969 AddInstruction(context); 3972 AddInstruction(context);
3970 HCall* call = new HCallNamed(context, name, argument_count); 3973 HCallNamed* call = new HCallNamed(context, name, argument_count);
3971 call->set_position(expr->position()); 3974 call->set_position(expr->position());
3972 PreProcessCall(call); 3975 PreProcessCall(call);
3973 ast_context()->ReturnInstruction(call, expr->id()); 3976 ast_context()->ReturnInstruction(call, expr->id());
3974 } else { 3977 } else {
3975 // Build subgraph for generic call through IC. 3978 // Build subgraph for generic call through IC.
3976 HSubgraph* default_graph = CreateBranchSubgraph(environment()); 3979 HSubgraph* default_graph = CreateBranchSubgraph(environment());
3977 { SubgraphScope scope(this, default_graph); 3980 { SubgraphScope scope(this, default_graph);
3978 if (!needs_generic && FLAG_deoptimize_uncommon_cases) { 3981 if (!needs_generic && FLAG_deoptimize_uncommon_cases) {
3979 default_graph->FinishExit(new HDeoptimize()); 3982 default_graph->FinishExit(new HDeoptimize());
3980 } else { 3983 } else {
3981 HContext* context = new HContext; 3984 HContext* context = new HContext;
3982 AddInstruction(context); 3985 AddInstruction(context);
3983 HCall* call = new HCallNamed(context, name, argument_count); 3986 HCallNamed* call = new HCallNamed(context, name, argument_count);
3984 call->set_position(expr->position()); 3987 call->set_position(expr->position());
3985 PreProcessCall(call); 3988 PreProcessCall(call);
3986 PushAndAdd(call); 3989 PushAndAdd(call);
3987 } 3990 }
3988 } 3991 }
3989 3992
3990 HBasicBlock* new_exit_block = 3993 HBasicBlock* new_exit_block =
3991 BuildTypeSwitch(receiver, &maps, &subgraphs, default_graph, expr->id()); 3994 BuildTypeSwitch(receiver, &maps, &subgraphs, default_graph, expr->id());
3992 set_current_block(new_exit_block); 3995 set_current_block(new_exit_block);
3993 // In an effect context, we did not materialized the value in the 3996 // In an effect context, we did not materialized the value in the
(...skipping 382 matching lines...) Expand 10 before | Expand all | Expand 10 after
4376 static bool HasCustomCallGenerator(Handle<JSFunction> function) { 4379 static bool HasCustomCallGenerator(Handle<JSFunction> function) {
4377 SharedFunctionInfo* info = function->shared(); 4380 SharedFunctionInfo* info = function->shared();
4378 return info->HasBuiltinFunctionId() && 4381 return info->HasBuiltinFunctionId() &&
4379 CallStubCompiler::HasCustomCallGenerator(info->builtin_function_id()); 4382 CallStubCompiler::HasCustomCallGenerator(info->builtin_function_id());
4380 } 4383 }
4381 4384
4382 4385
4383 void HGraphBuilder::VisitCall(Call* expr) { 4386 void HGraphBuilder::VisitCall(Call* expr) {
4384 Expression* callee = expr->expression(); 4387 Expression* callee = expr->expression();
4385 int argument_count = expr->arguments()->length() + 1; // Plus receiver. 4388 int argument_count = expr->arguments()->length() + 1; // Plus receiver.
4386 HCall* call = NULL; 4389 HInstruction* call = NULL;
4387 4390
4388 Property* prop = callee->AsProperty(); 4391 Property* prop = callee->AsProperty();
4389 if (prop != NULL) { 4392 if (prop != NULL) {
4390 if (!prop->key()->IsPropertyName()) { 4393 if (!prop->key()->IsPropertyName()) {
4391 // Keyed function call. 4394 // Keyed function call.
4392 VISIT_FOR_VALUE(prop->obj()); 4395 VISIT_FOR_VALUE(prop->obj());
4393 4396
4394 VISIT_FOR_VALUE(prop->key()); 4397 VISIT_FOR_VALUE(prop->key());
4395 // Push receiver and key like the non-optimized code generator expects it. 4398 // Push receiver and key like the non-optimized code generator expects it.
4396 HValue* key = Pop(); 4399 HValue* key = Pop();
4397 HValue* receiver = Pop(); 4400 HValue* receiver = Pop();
4398 Push(key); 4401 Push(key);
4399 Push(receiver); 4402 Push(receiver);
4400 4403
4401 VisitExpressions(expr->arguments()); 4404 VisitExpressions(expr->arguments());
4402 CHECK_BAILOUT; 4405 CHECK_BAILOUT;
4403 4406
4404 HContext* context = new HContext; 4407 HContext* context = new HContext;
4405 AddInstruction(context); 4408 AddInstruction(context);
4406 call = new HCallKeyed(context, key, argument_count); 4409 call = PreProcessCall(new HCallKeyed(context, key, argument_count));
4407 call->set_position(expr->position()); 4410 call->set_position(expr->position());
4408 PreProcessCall(call);
4409 Drop(1); // Key. 4411 Drop(1); // Key.
4410 ast_context()->ReturnInstruction(call, expr->id()); 4412 ast_context()->ReturnInstruction(call, expr->id());
4411 return; 4413 return;
4412 } 4414 }
4413 4415
4414 // Named function call. 4416 // Named function call.
4415 expr->RecordTypeFeedback(oracle()); 4417 expr->RecordTypeFeedback(oracle());
4416 4418
4417 if (TryCallApply(expr)) return; 4419 if (TryCallApply(expr)) return;
4418 CHECK_BAILOUT; 4420 CHECK_BAILOUT;
(...skipping 19 matching lines...) Expand all
4438 return; 4440 return;
4439 } 4441 }
4440 4442
4441 if (HasCustomCallGenerator(expr->target()) || 4443 if (HasCustomCallGenerator(expr->target()) ||
4442 expr->check_type() != RECEIVER_MAP_CHECK) { 4444 expr->check_type() != RECEIVER_MAP_CHECK) {
4443 // When the target has a custom call IC generator, use the IC, 4445 // When the target has a custom call IC generator, use the IC,
4444 // because it is likely to generate better code. Also use the 4446 // because it is likely to generate better code. Also use the
4445 // IC when a primitive receiver check is required. 4447 // IC when a primitive receiver check is required.
4446 HContext* context = new HContext; 4448 HContext* context = new HContext;
4447 AddInstruction(context); 4449 AddInstruction(context);
4448 call = new HCallNamed(context, name, argument_count); 4450 call = PreProcessCall(new HCallNamed(context, name, argument_count));
4449 } else { 4451 } else {
4450 AddCheckConstantFunction(expr, receiver, receiver_map, true); 4452 AddCheckConstantFunction(expr, receiver, receiver_map, true);
4451 4453
4452 if (TryInline(expr)) { 4454 if (TryInline(expr)) {
4453 if (current_block() != NULL) { 4455 if (current_block() != NULL) {
4454 HValue* return_value = Pop(); 4456 HValue* return_value = Pop();
4455 // If we inlined a function in a test context then we need to emit 4457 // If we inlined a function in a test context then we need to emit
4456 // a simulate here to shadow the ones at the end of the 4458 // a simulate here to shadow the ones at the end of the
4457 // predecessor blocks. Those environments contain the return 4459 // predecessor blocks. Those environments contain the return
4458 // value on top and do not correspond to any actual state of the 4460 // value on top and do not correspond to any actual state of the
4459 // unoptimized code. 4461 // unoptimized code.
4460 if (ast_context()->IsEffect()) AddSimulate(expr->id()); 4462 if (ast_context()->IsEffect()) AddSimulate(expr->id());
4461 ast_context()->ReturnValue(return_value); 4463 ast_context()->ReturnValue(return_value);
4462 } 4464 }
4463 return; 4465 return;
4464 } else { 4466 } else {
4465 // Check for bailout, as the TryInline call in the if condition above 4467 // Check for bailout, as the TryInline call in the if condition above
4466 // might return false due to bailout during hydrogen processing. 4468 // might return false due to bailout during hydrogen processing.
4467 CHECK_BAILOUT; 4469 CHECK_BAILOUT;
4468 call = new HCallConstantFunction(expr->target(), argument_count); 4470 call = PreProcessCall(new HCallConstantFunction(expr->target(),
4471 argument_count));
4469 } 4472 }
4470 } 4473 }
4471 } else if (types != NULL && types->length() > 1) { 4474 } else if (types != NULL && types->length() > 1) {
4472 ASSERT(expr->check_type() == RECEIVER_MAP_CHECK); 4475 ASSERT(expr->check_type() == RECEIVER_MAP_CHECK);
4473 HandlePolymorphicCallNamed(expr, receiver, types, name); 4476 HandlePolymorphicCallNamed(expr, receiver, types, name);
4474 return; 4477 return;
4475 4478
4476 } else { 4479 } else {
4477 HContext* context = new HContext; 4480 HContext* context = new HContext;
4478 AddInstruction(context); 4481 AddInstruction(context);
4479 call = new HCallNamed(context, name, argument_count); 4482 call = PreProcessCall(new HCallNamed(context, name, argument_count));
4480 } 4483 }
4481 4484
4482 } else { 4485 } else {
4483 Variable* var = expr->expression()->AsVariableProxy()->AsVariable(); 4486 Variable* var = expr->expression()->AsVariableProxy()->AsVariable();
4484 bool global_call = (var != NULL) && var->is_global() && !var->is_this(); 4487 bool global_call = (var != NULL) && var->is_global() && !var->is_this();
4485 4488
4486 if (!global_call) { 4489 if (!global_call) {
4487 ++argument_count; 4490 ++argument_count;
4488 VISIT_FOR_VALUE(expr->expression()); 4491 VISIT_FOR_VALUE(expr->expression());
4489 } 4492 }
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after
4530 // unoptimized code. 4533 // unoptimized code.
4531 if (ast_context()->IsEffect()) AddSimulate(expr->id()); 4534 if (ast_context()->IsEffect()) AddSimulate(expr->id());
4532 ast_context()->ReturnValue(return_value); 4535 ast_context()->ReturnValue(return_value);
4533 } 4536 }
4534 return; 4537 return;
4535 } 4538 }
4536 // Check for bailout, as trying to inline might fail due to bailout 4539 // Check for bailout, as trying to inline might fail due to bailout
4537 // during hydrogen processing. 4540 // during hydrogen processing.
4538 CHECK_BAILOUT; 4541 CHECK_BAILOUT;
4539 4542
4540 call = new HCallKnownGlobal(expr->target(), argument_count); 4543 call = PreProcessCall(new HCallKnownGlobal(expr->target(),
4544 argument_count));
4541 } else { 4545 } else {
4542 HContext* context = new HContext; 4546 HContext* context = new HContext;
4543 AddInstruction(context); 4547 AddInstruction(context);
4544 PushAndAdd(new HGlobalObject(context)); 4548 PushAndAdd(new HGlobalObject(context));
4545 VisitExpressions(expr->arguments()); 4549 VisitExpressions(expr->arguments());
4546 CHECK_BAILOUT; 4550 CHECK_BAILOUT;
4547 4551
4548 call = new HCallGlobal(context, var->name(), argument_count); 4552 call = PreProcessCall(new HCallGlobal(context,
4553 var->name(),
4554 argument_count));
4549 } 4555 }
4550 4556
4551 } else { 4557 } else {
4552 HContext* context = new HContext; 4558 HContext* context = new HContext;
4553 HGlobalObject* global_object = new HGlobalObject(context); 4559 HGlobalObject* global_object = new HGlobalObject(context);
4554 AddInstruction(context); 4560 AddInstruction(context);
4555 AddInstruction(global_object); 4561 AddInstruction(global_object);
4556 PushAndAdd(new HGlobalReceiver(global_object)); 4562 PushAndAdd(new HGlobalReceiver(global_object));
4557 VisitExpressions(expr->arguments()); 4563 VisitExpressions(expr->arguments());
4558 CHECK_BAILOUT; 4564 CHECK_BAILOUT;
4559 4565
4560 call = new HCallFunction(context, argument_count); 4566 call = PreProcessCall(new HCallFunction(context, argument_count));
4561 } 4567 }
4562 } 4568 }
4563 4569
4564 call->set_position(expr->position()); 4570 call->set_position(expr->position());
4565 PreProcessCall(call);
4566 ast_context()->ReturnInstruction(call, expr->id()); 4571 ast_context()->ReturnInstruction(call, expr->id());
4567 } 4572 }
4568 4573
4569 4574
4570 void HGraphBuilder::VisitCallNew(CallNew* expr) { 4575 void HGraphBuilder::VisitCallNew(CallNew* expr) {
4571 // The constructor function is also used as the receiver argument to the 4576 // The constructor function is also used as the receiver argument to the
4572 // JS construct call builtin. 4577 // JS construct call builtin.
4573 VISIT_FOR_VALUE(expr->expression()); 4578 VISIT_FOR_VALUE(expr->expression());
4574 VisitExpressions(expr->arguments()); 4579 VisitExpressions(expr->arguments());
4575 CHECK_BAILOUT; 4580 CHECK_BAILOUT;
4576 4581
4577 HContext* context = new HContext; 4582 HContext* context = new HContext;
4578 AddInstruction(context); 4583 AddInstruction(context);
4579 4584
4580 // The constructor is both an operand to the instruction and an argument 4585 // The constructor is both an operand to the instruction and an argument
4581 // to the construct call. 4586 // to the construct call.
4582 int arg_count = expr->arguments()->length() + 1; // Plus constructor. 4587 int arg_count = expr->arguments()->length() + 1; // Plus constructor.
4583 HValue* constructor = environment()->ExpressionStackAt(arg_count - 1); 4588 HValue* constructor = environment()->ExpressionStackAt(arg_count - 1);
4584 HCall* call = new HCallNew(context, constructor, arg_count); 4589 HCallNew* call = new HCallNew(context, constructor, arg_count);
4585 call->set_position(expr->position()); 4590 call->set_position(expr->position());
4586 PreProcessCall(call); 4591 PreProcessCall(call);
4587 ast_context()->ReturnInstruction(call, expr->id()); 4592 ast_context()->ReturnInstruction(call, expr->id());
4588 } 4593 }
4589 4594
4590 4595
4591 // Support for generating inlined runtime functions. 4596 // Support for generating inlined runtime functions.
4592 4597
4593 // Lookup table for generators for runtime calls that are generated inline. 4598 // Lookup table for generators for runtime calls that are generated inline.
4594 // Elements of the table are member pointers to functions of HGraphBuilder. 4599 // Elements of the table are member pointers to functions of HGraphBuilder.
(...skipping 28 matching lines...) Expand all
4623 4628
4624 // Call the inline code generator using the pointer-to-member. 4629 // Call the inline code generator using the pointer-to-member.
4625 (this->*generator)(expr); 4630 (this->*generator)(expr);
4626 } else { 4631 } else {
4627 ASSERT(function->intrinsic_type == Runtime::RUNTIME); 4632 ASSERT(function->intrinsic_type == Runtime::RUNTIME);
4628 VisitArgumentList(expr->arguments()); 4633 VisitArgumentList(expr->arguments());
4629 CHECK_BAILOUT; 4634 CHECK_BAILOUT;
4630 4635
4631 Handle<String> name = expr->name(); 4636 Handle<String> name = expr->name();
4632 int argument_count = expr->arguments()->length(); 4637 int argument_count = expr->arguments()->length();
4633 HCall* call = new HCallRuntime(name, function, argument_count); 4638 HCallRuntime* call = new HCallRuntime(name, function, argument_count);
4634 call->set_position(RelocInfo::kNoPosition); 4639 call->set_position(RelocInfo::kNoPosition);
4635 Drop(argument_count); 4640 Drop(argument_count);
4636 ast_context()->ReturnInstruction(call, expr->id()); 4641 ast_context()->ReturnInstruction(call, expr->id());
4637 } 4642 }
4638 } 4643 }
4639 4644
4640 4645
4641 void HGraphBuilder::VisitUnaryOperation(UnaryOperation* expr) { 4646 void HGraphBuilder::VisitUnaryOperation(UnaryOperation* expr) {
4642 Token::Value op = expr->op(); 4647 Token::Value op = expr->op();
4643 if (op == Token::VOID) { 4648 if (op == Token::VOID) {
(...skipping 1446 matching lines...) Expand 10 before | Expand all | Expand 10 after
6090 } 6095 }
6091 } 6096 }
6092 6097
6093 #ifdef DEBUG 6098 #ifdef DEBUG
6094 if (graph_ != NULL) graph_->Verify(); 6099 if (graph_ != NULL) graph_->Verify();
6095 if (allocator_ != NULL) allocator_->Verify(); 6100 if (allocator_ != NULL) allocator_->Verify();
6096 #endif 6101 #endif
6097 } 6102 }
6098 6103
6099 } } // namespace v8::internal 6104 } } // 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