OLD | NEW |
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 2175 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2186 | 2186 |
2187 | 2187 |
2188 void HGraphBuilder::VisitForControl(Expression* expr, | 2188 void HGraphBuilder::VisitForControl(Expression* expr, |
2189 HBasicBlock* true_block, | 2189 HBasicBlock* true_block, |
2190 HBasicBlock* false_block) { | 2190 HBasicBlock* false_block) { |
2191 TestContext for_test(this, true_block, false_block); | 2191 TestContext for_test(this, true_block, false_block); |
2192 Visit(expr); | 2192 Visit(expr); |
2193 } | 2193 } |
2194 | 2194 |
2195 | 2195 |
2196 HValue* HGraphBuilder::VisitArgument(Expression* expr) { | 2196 void HGraphBuilder::VisitArgument(Expression* expr) { |
2197 VisitForValue(expr); | 2197 VisitForValue(expr); |
2198 if (HasStackOverflow() || !subgraph()->HasExit()) return NULL; | |
2199 return environment()->Top(); | |
2200 } | 2198 } |
2201 | 2199 |
2202 | 2200 |
2203 void HGraphBuilder::VisitArgumentList(ZoneList<Expression*>* arguments) { | 2201 void HGraphBuilder::VisitArgumentList(ZoneList<Expression*>* arguments) { |
2204 for (int i = 0; i < arguments->length(); i++) { | 2202 for (int i = 0; i < arguments->length(); i++) { |
2205 VisitArgument(arguments->at(i)); | 2203 VisitArgument(arguments->at(i)); |
2206 if (HasStackOverflow() || !current_subgraph_->HasExit()) return; | 2204 if (HasStackOverflow() || !current_subgraph_->HasExit()) return; |
2207 } | 2205 } |
2208 } | 2206 } |
2209 | 2207 |
(...skipping 98 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2308 current_subgraph_->exit_block()->AddPhi(instr); | 2306 current_subgraph_->exit_block()->AddPhi(instr); |
2309 } | 2307 } |
2310 | 2308 |
2311 | 2309 |
2312 void HGraphBuilder::PushAndAdd(HInstruction* instr) { | 2310 void HGraphBuilder::PushAndAdd(HInstruction* instr) { |
2313 Push(instr); | 2311 Push(instr); |
2314 AddInstruction(instr); | 2312 AddInstruction(instr); |
2315 } | 2313 } |
2316 | 2314 |
2317 | 2315 |
2318 void HGraphBuilder::PushArgumentsForStubCall(int argument_count) { | 2316 void HGraphBuilder::PreProcessCall(HCall* call) { |
2319 const int kMaxStubArguments = 4; | 2317 int count = call->argument_count(); |
2320 ASSERT_GE(kMaxStubArguments, argument_count); | 2318 ZoneList<HValue*> arguments(count); |
2321 // Push the arguments on the stack. | 2319 for (int i = 0; i < count; ++i) { |
2322 HValue* arguments[kMaxStubArguments]; | 2320 arguments.Add(Pop()); |
2323 for (int i = argument_count - 1; i >= 0; i--) { | |
2324 arguments[i] = Pop(); | |
2325 } | 2321 } |
2326 for (int i = 0; i < argument_count; i++) { | 2322 |
2327 AddInstruction(new HPushArgument(arguments[i])); | 2323 while (!arguments.is_empty()) { |
| 2324 AddInstruction(new HPushArgument(arguments.RemoveLast())); |
2328 } | 2325 } |
2329 } | 2326 } |
2330 | 2327 |
2331 | |
2332 void HGraphBuilder::ProcessCall(HCall* call) { | |
2333 for (int i = call->argument_count() - 1; i >= 0; --i) { | |
2334 HValue* value = Pop(); | |
2335 HPushArgument* push = new HPushArgument(value); | |
2336 call->SetArgumentAt(i, push); | |
2337 } | |
2338 | |
2339 for (int i = 0; i < call->argument_count(); ++i) { | |
2340 AddInstruction(call->PushArgumentAt(i)); | |
2341 } | |
2342 } | |
2343 | |
2344 | 2328 |
2345 void HGraphBuilder::SetupScope(Scope* scope) { | 2329 void HGraphBuilder::SetupScope(Scope* scope) { |
2346 // We don't yet handle the function name for named function expressions. | 2330 // We don't yet handle the function name for named function expressions. |
2347 if (scope->function() != NULL) BAILOUT("named function expression"); | 2331 if (scope->function() != NULL) BAILOUT("named function expression"); |
2348 | 2332 |
2349 // We can't handle heap-allocated locals. | 2333 // We can't handle heap-allocated locals. |
2350 if (scope->num_heap_slots() > 0) BAILOUT("heap allocated locals"); | 2334 if (scope->num_heap_slots() > 0) BAILOUT("heap allocated locals"); |
2351 | 2335 |
2352 HConstant* undefined_constant = | 2336 HConstant* undefined_constant = |
2353 new HConstant(Factory::undefined_value(), Representation::Tagged()); | 2337 new HConstant(Factory::undefined_value(), Representation::Tagged()); |
(...skipping 1584 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3938 if (FLAG_trace_inlining && FLAG_polymorphic_inlining) { | 3922 if (FLAG_trace_inlining && FLAG_polymorphic_inlining) { |
3939 PrintF("Trying to inline the polymorphic call to %s\n", | 3923 PrintF("Trying to inline the polymorphic call to %s\n", |
3940 *name->ToCString()); | 3924 *name->ToCString()); |
3941 } | 3925 } |
3942 if (!FLAG_polymorphic_inlining || !TryInline(expr)) { | 3926 if (!FLAG_polymorphic_inlining || !TryInline(expr)) { |
3943 // Check for bailout, as trying to inline might fail due to bailout | 3927 // Check for bailout, as trying to inline might fail due to bailout |
3944 // during hydrogen processing. | 3928 // during hydrogen processing. |
3945 CHECK_BAILOUT; | 3929 CHECK_BAILOUT; |
3946 HCall* call = new HCallConstantFunction(expr->target(), argument_count); | 3930 HCall* call = new HCallConstantFunction(expr->target(), argument_count); |
3947 call->set_position(expr->position()); | 3931 call->set_position(expr->position()); |
3948 ProcessCall(call); | 3932 PreProcessCall(call); |
3949 PushAndAdd(call); | 3933 PushAndAdd(call); |
3950 } | 3934 } |
3951 subgraphs.Add(subgraph); | 3935 subgraphs.Add(subgraph); |
3952 } else { | 3936 } else { |
3953 needs_generic = true; | 3937 needs_generic = true; |
3954 } | 3938 } |
3955 } | 3939 } |
3956 | 3940 |
3957 // If we couldn't compute the target for any of the maps just perform an | 3941 // If we couldn't compute the target for any of the maps just perform an |
3958 // IC call. | 3942 // IC call. |
3959 if (maps.length() == 0) { | 3943 if (maps.length() == 0) { |
3960 HContext* context = new HContext; | 3944 HContext* context = new HContext; |
3961 AddInstruction(context); | 3945 AddInstruction(context); |
3962 HCall* call = new HCallNamed(context, name, argument_count); | 3946 HCall* call = new HCallNamed(context, name, argument_count); |
3963 call->set_position(expr->position()); | 3947 call->set_position(expr->position()); |
3964 ProcessCall(call); | 3948 PreProcessCall(call); |
3965 ast_context()->ReturnInstruction(call, expr->id()); | 3949 ast_context()->ReturnInstruction(call, expr->id()); |
3966 } else { | 3950 } else { |
3967 // Build subgraph for generic call through IC. | 3951 // Build subgraph for generic call through IC. |
3968 { | 3952 { |
3969 HSubgraph* subgraph = CreateBranchSubgraph(environment()); | 3953 HSubgraph* subgraph = CreateBranchSubgraph(environment()); |
3970 SubgraphScope scope(this, subgraph); | 3954 SubgraphScope scope(this, subgraph); |
3971 if (!needs_generic && FLAG_deoptimize_uncommon_cases) { | 3955 if (!needs_generic && FLAG_deoptimize_uncommon_cases) { |
3972 subgraph->FinishExit(new HDeoptimize()); | 3956 subgraph->FinishExit(new HDeoptimize()); |
3973 } else { | 3957 } else { |
3974 HContext* context = new HContext; | 3958 HContext* context = new HContext; |
3975 AddInstruction(context); | 3959 AddInstruction(context); |
3976 HCall* call = new HCallNamed(context, name, argument_count); | 3960 HCall* call = new HCallNamed(context, name, argument_count); |
3977 call->set_position(expr->position()); | 3961 call->set_position(expr->position()); |
3978 ProcessCall(call); | 3962 PreProcessCall(call); |
3979 PushAndAdd(call); | 3963 PushAndAdd(call); |
3980 } | 3964 } |
3981 subgraphs.Add(subgraph); | 3965 subgraphs.Add(subgraph); |
3982 } | 3966 } |
3983 | 3967 |
3984 HBasicBlock* new_exit_block = | 3968 HBasicBlock* new_exit_block = |
3985 BuildTypeSwitch(&maps, &subgraphs, receiver, expr->id()); | 3969 BuildTypeSwitch(&maps, &subgraphs, receiver, expr->id()); |
3986 subgraph()->set_exit_block(new_exit_block); | 3970 subgraph()->set_exit_block(new_exit_block); |
3987 // In an effect context, we did not materialized the value in the | 3971 // In an effect context, we did not materialized the value in the |
3988 // predecessor environments so there's no need to handle it here. | 3972 // predecessor environments so there's no need to handle it here. |
(...skipping 401 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4390 Push(key); | 4374 Push(key); |
4391 Push(receiver); | 4375 Push(receiver); |
4392 | 4376 |
4393 VisitArgumentList(expr->arguments()); | 4377 VisitArgumentList(expr->arguments()); |
4394 CHECK_BAILOUT; | 4378 CHECK_BAILOUT; |
4395 | 4379 |
4396 HContext* context = new HContext; | 4380 HContext* context = new HContext; |
4397 AddInstruction(context); | 4381 AddInstruction(context); |
4398 call = new HCallKeyed(context, key, argument_count); | 4382 call = new HCallKeyed(context, key, argument_count); |
4399 call->set_position(expr->position()); | 4383 call->set_position(expr->position()); |
4400 ProcessCall(call); | 4384 PreProcessCall(call); |
4401 Drop(1); // Key. | 4385 Drop(1); // Key. |
4402 ast_context()->ReturnInstruction(call, expr->id()); | 4386 ast_context()->ReturnInstruction(call, expr->id()); |
4403 return; | 4387 return; |
4404 } | 4388 } |
4405 | 4389 |
4406 // Named function call. | 4390 // Named function call. |
4407 expr->RecordTypeFeedback(oracle()); | 4391 expr->RecordTypeFeedback(oracle()); |
4408 | 4392 |
4409 if (TryCallApply(expr)) return; | 4393 if (TryCallApply(expr)) return; |
4410 CHECK_BAILOUT; | 4394 CHECK_BAILOUT; |
4411 | 4395 |
4412 HValue* receiver = VisitArgument(prop->obj()); | 4396 VisitArgument(prop->obj()); |
4413 CHECK_BAILOUT; | 4397 CHECK_BAILOUT; |
4414 VisitArgumentList(expr->arguments()); | 4398 VisitArgumentList(expr->arguments()); |
4415 CHECK_BAILOUT; | 4399 CHECK_BAILOUT; |
4416 | 4400 |
4417 Handle<String> name = prop->key()->AsLiteral()->AsPropertyName(); | 4401 Handle<String> name = prop->key()->AsLiteral()->AsPropertyName(); |
4418 | 4402 |
4419 expr->RecordTypeFeedback(oracle()); | 4403 expr->RecordTypeFeedback(oracle()); |
4420 ZoneMapList* types = expr->GetReceiverTypes(); | 4404 ZoneMapList* types = expr->GetReceiverTypes(); |
4421 | 4405 |
| 4406 HValue* receiver = |
| 4407 environment()->ExpressionStackAt(expr->arguments()->length()); |
4422 if (expr->IsMonomorphic()) { | 4408 if (expr->IsMonomorphic()) { |
4423 Handle<Map> receiver_map = | 4409 Handle<Map> receiver_map = |
4424 (types == NULL) ? Handle<Map>::null() : types->first(); | 4410 (types == NULL) ? Handle<Map>::null() : types->first(); |
4425 if (TryInlineBuiltinFunction(expr, | 4411 if (TryInlineBuiltinFunction(expr, |
4426 receiver, | 4412 receiver, |
4427 receiver_map, | 4413 receiver_map, |
4428 expr->check_type())) { | 4414 expr->check_type())) { |
4429 return; | 4415 return; |
4430 } | 4416 } |
4431 | 4417 |
(...skipping 115 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4547 AddInstruction(global_object); | 4533 AddInstruction(global_object); |
4548 PushAndAdd(new HGlobalReceiver(global_object)); | 4534 PushAndAdd(new HGlobalReceiver(global_object)); |
4549 VisitArgumentList(expr->arguments()); | 4535 VisitArgumentList(expr->arguments()); |
4550 CHECK_BAILOUT; | 4536 CHECK_BAILOUT; |
4551 | 4537 |
4552 call = new HCallFunction(context, argument_count); | 4538 call = new HCallFunction(context, argument_count); |
4553 } | 4539 } |
4554 } | 4540 } |
4555 | 4541 |
4556 call->set_position(expr->position()); | 4542 call->set_position(expr->position()); |
4557 ProcessCall(call); | 4543 PreProcessCall(call); |
4558 ast_context()->ReturnInstruction(call, expr->id()); | 4544 ast_context()->ReturnInstruction(call, expr->id()); |
4559 } | 4545 } |
4560 | 4546 |
4561 | 4547 |
4562 void HGraphBuilder::VisitCallNew(CallNew* expr) { | 4548 void HGraphBuilder::VisitCallNew(CallNew* expr) { |
4563 // The constructor function is also used as the receiver argument to the | 4549 // The constructor function is also used as the receiver argument to the |
4564 // JS construct call builtin. | 4550 // JS construct call builtin. |
4565 VisitArgument(expr->expression()); | 4551 VisitArgument(expr->expression()); |
4566 CHECK_BAILOUT; | 4552 CHECK_BAILOUT; |
4567 VisitArgumentList(expr->arguments()); | 4553 VisitArgumentList(expr->arguments()); |
4568 CHECK_BAILOUT; | 4554 CHECK_BAILOUT; |
4569 | 4555 |
4570 int argument_count = expr->arguments()->length() + 1; // Plus constructor. | |
4571 HContext* context = new HContext; | 4556 HContext* context = new HContext; |
4572 AddInstruction(context); | 4557 AddInstruction(context); |
4573 HCall* call = new HCallNew(context, argument_count); | 4558 |
| 4559 // The constructor is both an operand to the instruction and an argument |
| 4560 // to the construct call. |
| 4561 int arg_count = expr->arguments()->length() + 1; // Plus constructor. |
| 4562 HValue* constructor = environment()->ExpressionStackAt(arg_count - 1); |
| 4563 HCall* call = new HCallNew(context, constructor, arg_count); |
4574 call->set_position(expr->position()); | 4564 call->set_position(expr->position()); |
4575 ProcessCall(call); | 4565 PreProcessCall(call); |
4576 ast_context()->ReturnInstruction(call, expr->id()); | 4566 ast_context()->ReturnInstruction(call, expr->id()); |
4577 } | 4567 } |
4578 | 4568 |
4579 | 4569 |
4580 // Support for generating inlined runtime functions. | 4570 // Support for generating inlined runtime functions. |
4581 | 4571 |
4582 // Lookup table for generators for runtime calls that are generated inline. | 4572 // Lookup table for generators for runtime calls that are generated inline. |
4583 // Elements of the table are member pointers to functions of HGraphBuilder. | 4573 // Elements of the table are member pointers to functions of HGraphBuilder. |
4584 #define INLINE_FUNCTION_GENERATOR_ADDRESS(Name, argc, ressize) \ | 4574 #define INLINE_FUNCTION_GENERATOR_ADDRESS(Name, argc, ressize) \ |
4585 &HGraphBuilder::Generate##Name, | 4575 &HGraphBuilder::Generate##Name, |
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4619 ASSERT(static_cast<size_t>(lookup_index) < | 4609 ASSERT(static_cast<size_t>(lookup_index) < |
4620 ARRAY_SIZE(kInlineFunctionGenerators)); | 4610 ARRAY_SIZE(kInlineFunctionGenerators)); |
4621 InlineFunctionGenerator generator = kInlineFunctionGenerators[lookup_index]; | 4611 InlineFunctionGenerator generator = kInlineFunctionGenerators[lookup_index]; |
4622 | 4612 |
4623 // Call the inline code generator using the pointer-to-member. | 4613 // Call the inline code generator using the pointer-to-member. |
4624 (this->*generator)(argument_count, expr->id()); | 4614 (this->*generator)(argument_count, expr->id()); |
4625 } else { | 4615 } else { |
4626 ASSERT(function->intrinsic_type == Runtime::RUNTIME); | 4616 ASSERT(function->intrinsic_type == Runtime::RUNTIME); |
4627 HCall* call = new HCallRuntime(name, expr->function(), argument_count); | 4617 HCall* call = new HCallRuntime(name, expr->function(), argument_count); |
4628 call->set_position(RelocInfo::kNoPosition); | 4618 call->set_position(RelocInfo::kNoPosition); |
4629 ProcessCall(call); | 4619 PreProcessCall(call); |
4630 ast_context()->ReturnInstruction(call, expr->id()); | 4620 ast_context()->ReturnInstruction(call, expr->id()); |
4631 } | 4621 } |
4632 } | 4622 } |
4633 | 4623 |
4634 | 4624 |
4635 void HGraphBuilder::VisitUnaryOperation(UnaryOperation* expr) { | 4625 void HGraphBuilder::VisitUnaryOperation(UnaryOperation* expr) { |
4636 Token::Value op = expr->op(); | 4626 Token::Value op = expr->op(); |
4637 if (op == Token::VOID) { | 4627 if (op == Token::VOID) { |
4638 VISIT_FOR_EFFECT(expr->expression()); | 4628 VISIT_FOR_EFFECT(expr->expression()); |
4639 ast_context()->ReturnValue(graph()->GetConstantUndefined()); | 4629 ast_context()->ReturnValue(graph()->GetConstantUndefined()); |
(...skipping 660 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5300 // Fast support for string.charAt(n) and string[n]. | 5290 // Fast support for string.charAt(n) and string[n]. |
5301 void HGraphBuilder::GenerateStringCharFromCode(int argument_count, | 5291 void HGraphBuilder::GenerateStringCharFromCode(int argument_count, |
5302 int ast_id) { | 5292 int ast_id) { |
5303 BAILOUT("inlined runtime function: StringCharFromCode"); | 5293 BAILOUT("inlined runtime function: StringCharFromCode"); |
5304 } | 5294 } |
5305 | 5295 |
5306 | 5296 |
5307 // Fast support for string.charAt(n) and string[n]. | 5297 // Fast support for string.charAt(n) and string[n]. |
5308 void HGraphBuilder::GenerateStringCharAt(int argument_count, int ast_id) { | 5298 void HGraphBuilder::GenerateStringCharAt(int argument_count, int ast_id) { |
5309 ASSERT_EQ(2, argument_count); | 5299 ASSERT_EQ(2, argument_count); |
5310 PushArgumentsForStubCall(argument_count); | |
5311 HContext* context = new HContext; | 5300 HContext* context = new HContext; |
5312 AddInstruction(context); | 5301 AddInstruction(context); |
5313 HCallStub* result = | 5302 HCallStub* result = |
5314 new HCallStub(context, CodeStub::StringCharAt, argument_count); | 5303 new HCallStub(context, CodeStub::StringCharAt, argument_count); |
| 5304 PreProcessCall(result); |
5315 ast_context()->ReturnInstruction(result, ast_id); | 5305 ast_context()->ReturnInstruction(result, ast_id); |
5316 } | 5306 } |
5317 | 5307 |
5318 | 5308 |
5319 // Fast support for object equality testing. | 5309 // Fast support for object equality testing. |
5320 void HGraphBuilder::GenerateObjectEquals(int argument_count, int ast_id) { | 5310 void HGraphBuilder::GenerateObjectEquals(int argument_count, int ast_id) { |
5321 ASSERT(argument_count == 2); | 5311 ASSERT(argument_count == 2); |
5322 HValue* right = Pop(); | 5312 HValue* right = Pop(); |
5323 HValue* left = Pop(); | 5313 HValue* left = Pop(); |
5324 HCompareJSObjectEq* result = new HCompareJSObjectEq(left, right); | 5314 HCompareJSObjectEq* result = new HCompareJSObjectEq(left, right); |
5325 ast_context()->ReturnInstruction(result, ast_id); | 5315 ast_context()->ReturnInstruction(result, ast_id); |
5326 } | 5316 } |
5327 | 5317 |
5328 | 5318 |
5329 void HGraphBuilder::GenerateLog(int argument_count, int ast_id) { | 5319 void HGraphBuilder::GenerateLog(int argument_count, int ast_id) { |
5330 UNREACHABLE(); // We caught this in VisitCallRuntime. | 5320 UNREACHABLE(); // We caught this in VisitCallRuntime. |
5331 } | 5321 } |
5332 | 5322 |
5333 | 5323 |
5334 // Fast support for Math.random(). | 5324 // Fast support for Math.random(). |
5335 void HGraphBuilder::GenerateRandomHeapNumber(int argument_count, int ast_id) { | 5325 void HGraphBuilder::GenerateRandomHeapNumber(int argument_count, int ast_id) { |
5336 BAILOUT("inlined runtime function: RandomHeapNumber"); | 5326 BAILOUT("inlined runtime function: RandomHeapNumber"); |
5337 } | 5327 } |
5338 | 5328 |
5339 | 5329 |
5340 // Fast support for StringAdd. | 5330 // Fast support for StringAdd. |
5341 void HGraphBuilder::GenerateStringAdd(int argument_count, int ast_id) { | 5331 void HGraphBuilder::GenerateStringAdd(int argument_count, int ast_id) { |
5342 ASSERT_EQ(2, argument_count); | 5332 ASSERT_EQ(2, argument_count); |
5343 PushArgumentsForStubCall(argument_count); | |
5344 HContext* context = new HContext; | 5333 HContext* context = new HContext; |
5345 AddInstruction(context); | 5334 AddInstruction(context); |
5346 HCallStub* result = | 5335 HCallStub* result = |
5347 new HCallStub(context, CodeStub::StringAdd, argument_count); | 5336 new HCallStub(context, CodeStub::StringAdd, argument_count); |
| 5337 PreProcessCall(result); |
5348 ast_context()->ReturnInstruction(result, ast_id); | 5338 ast_context()->ReturnInstruction(result, ast_id); |
5349 } | 5339 } |
5350 | 5340 |
5351 | 5341 |
5352 // Fast support for SubString. | 5342 // Fast support for SubString. |
5353 void HGraphBuilder::GenerateSubString(int argument_count, int ast_id) { | 5343 void HGraphBuilder::GenerateSubString(int argument_count, int ast_id) { |
5354 ASSERT_EQ(3, argument_count); | 5344 ASSERT_EQ(3, argument_count); |
5355 PushArgumentsForStubCall(argument_count); | |
5356 HContext* context = new HContext; | 5345 HContext* context = new HContext; |
5357 AddInstruction(context); | 5346 AddInstruction(context); |
5358 HCallStub* result = | 5347 HCallStub* result = |
5359 new HCallStub(context, CodeStub::SubString, argument_count); | 5348 new HCallStub(context, CodeStub::SubString, argument_count); |
| 5349 PreProcessCall(result); |
5360 ast_context()->ReturnInstruction(result, ast_id); | 5350 ast_context()->ReturnInstruction(result, ast_id); |
5361 } | 5351 } |
5362 | 5352 |
5363 | 5353 |
5364 // Fast support for StringCompare. | 5354 // Fast support for StringCompare. |
5365 void HGraphBuilder::GenerateStringCompare(int argument_count, int ast_id) { | 5355 void HGraphBuilder::GenerateStringCompare(int argument_count, int ast_id) { |
5366 ASSERT_EQ(2, argument_count); | 5356 ASSERT_EQ(2, argument_count); |
5367 PushArgumentsForStubCall(argument_count); | |
5368 HContext* context = new HContext; | 5357 HContext* context = new HContext; |
5369 AddInstruction(context); | 5358 AddInstruction(context); |
5370 HCallStub* result = | 5359 HCallStub* result = |
5371 new HCallStub(context, CodeStub::StringCompare, argument_count); | 5360 new HCallStub(context, CodeStub::StringCompare, argument_count); |
| 5361 PreProcessCall(result); |
5372 ast_context()->ReturnInstruction(result, ast_id); | 5362 ast_context()->ReturnInstruction(result, ast_id); |
5373 } | 5363 } |
5374 | 5364 |
5375 | 5365 |
5376 // Support for direct calls from JavaScript to native RegExp code. | 5366 // Support for direct calls from JavaScript to native RegExp code. |
5377 void HGraphBuilder::GenerateRegExpExec(int argument_count, int ast_id) { | 5367 void HGraphBuilder::GenerateRegExpExec(int argument_count, int ast_id) { |
5378 ASSERT_EQ(4, argument_count); | 5368 ASSERT_EQ(4, argument_count); |
5379 PushArgumentsForStubCall(argument_count); | |
5380 HContext* context = new HContext; | 5369 HContext* context = new HContext; |
5381 AddInstruction(context); | 5370 AddInstruction(context); |
5382 HCallStub* result = | 5371 HCallStub* result = |
5383 new HCallStub(context, CodeStub::RegExpExec, argument_count); | 5372 new HCallStub(context, CodeStub::RegExpExec, argument_count); |
| 5373 PreProcessCall(result); |
5384 ast_context()->ReturnInstruction(result, ast_id); | 5374 ast_context()->ReturnInstruction(result, ast_id); |
5385 } | 5375 } |
5386 | 5376 |
5387 | 5377 |
5388 // Construct a RegExp exec result with two in-object properties. | 5378 // Construct a RegExp exec result with two in-object properties. |
5389 void HGraphBuilder::GenerateRegExpConstructResult(int argument_count, | 5379 void HGraphBuilder::GenerateRegExpConstructResult(int argument_count, |
5390 int ast_id) { | 5380 int ast_id) { |
5391 ASSERT_EQ(3, argument_count); | 5381 ASSERT_EQ(3, argument_count); |
5392 PushArgumentsForStubCall(argument_count); | |
5393 HContext* context = new HContext; | 5382 HContext* context = new HContext; |
5394 AddInstruction(context); | 5383 AddInstruction(context); |
5395 HCallStub* result = | 5384 HCallStub* result = |
5396 new HCallStub(context, CodeStub::RegExpConstructResult, argument_count); | 5385 new HCallStub(context, CodeStub::RegExpConstructResult, argument_count); |
| 5386 PreProcessCall(result); |
5397 ast_context()->ReturnInstruction(result, ast_id); | 5387 ast_context()->ReturnInstruction(result, ast_id); |
5398 } | 5388 } |
5399 | 5389 |
5400 | 5390 |
5401 // Support for fast native caches. | 5391 // Support for fast native caches. |
5402 void HGraphBuilder::GenerateGetFromCache(int argument_count, int ast_id) { | 5392 void HGraphBuilder::GenerateGetFromCache(int argument_count, int ast_id) { |
5403 BAILOUT("inlined runtime function: GetFromCache"); | 5393 BAILOUT("inlined runtime function: GetFromCache"); |
5404 } | 5394 } |
5405 | 5395 |
5406 | 5396 |
5407 // Fast support for number to string. | 5397 // Fast support for number to string. |
5408 void HGraphBuilder::GenerateNumberToString(int argument_count, int ast_id) { | 5398 void HGraphBuilder::GenerateNumberToString(int argument_count, int ast_id) { |
5409 ASSERT_EQ(1, argument_count); | 5399 ASSERT_EQ(1, argument_count); |
5410 PushArgumentsForStubCall(argument_count); | |
5411 HContext* context = new HContext; | 5400 HContext* context = new HContext; |
5412 AddInstruction(context); | 5401 AddInstruction(context); |
5413 HCallStub* result = | 5402 HCallStub* result = |
5414 new HCallStub(context, CodeStub::NumberToString, argument_count); | 5403 new HCallStub(context, CodeStub::NumberToString, argument_count); |
| 5404 PreProcessCall(result); |
5415 ast_context()->ReturnInstruction(result, ast_id); | 5405 ast_context()->ReturnInstruction(result, ast_id); |
5416 } | 5406 } |
5417 | 5407 |
5418 | 5408 |
5419 // Fast swapping of elements. Takes three expressions, the object and two | 5409 // Fast swapping of elements. Takes three expressions, the object and two |
5420 // indices. This should only be used if the indices are known to be | 5410 // indices. This should only be used if the indices are known to be |
5421 // non-negative and within bounds of the elements array at the call site. | 5411 // non-negative and within bounds of the elements array at the call site. |
5422 void HGraphBuilder::GenerateSwapElements(int argument_count, int ast_id) { | 5412 void HGraphBuilder::GenerateSwapElements(int argument_count, int ast_id) { |
5423 BAILOUT("inlined runtime function: SwapElements"); | 5413 BAILOUT("inlined runtime function: SwapElements"); |
5424 } | 5414 } |
(...skipping 10 matching lines...) Expand all Loading... |
5435 ASSERT_EQ(2, argument_count); | 5425 ASSERT_EQ(2, argument_count); |
5436 HValue* right = Pop(); | 5426 HValue* right = Pop(); |
5437 HValue* left = Pop(); | 5427 HValue* left = Pop(); |
5438 HPower* result = new HPower(left, right); | 5428 HPower* result = new HPower(left, right); |
5439 ast_context()->ReturnInstruction(result, ast_id); | 5429 ast_context()->ReturnInstruction(result, ast_id); |
5440 } | 5430 } |
5441 | 5431 |
5442 | 5432 |
5443 void HGraphBuilder::GenerateMathSin(int argument_count, int ast_id) { | 5433 void HGraphBuilder::GenerateMathSin(int argument_count, int ast_id) { |
5444 ASSERT_EQ(1, argument_count); | 5434 ASSERT_EQ(1, argument_count); |
5445 PushArgumentsForStubCall(argument_count); | |
5446 HContext* context = new HContext; | 5435 HContext* context = new HContext; |
5447 AddInstruction(context); | 5436 AddInstruction(context); |
5448 HCallStub* result = | 5437 HCallStub* result = |
5449 new HCallStub(context, CodeStub::TranscendentalCache, argument_count); | 5438 new HCallStub(context, CodeStub::TranscendentalCache, argument_count); |
5450 result->set_transcendental_type(TranscendentalCache::SIN); | 5439 result->set_transcendental_type(TranscendentalCache::SIN); |
| 5440 PreProcessCall(result); |
5451 ast_context()->ReturnInstruction(result, ast_id); | 5441 ast_context()->ReturnInstruction(result, ast_id); |
5452 } | 5442 } |
5453 | 5443 |
5454 | 5444 |
5455 void HGraphBuilder::GenerateMathCos(int argument_count, int ast_id) { | 5445 void HGraphBuilder::GenerateMathCos(int argument_count, int ast_id) { |
5456 ASSERT_EQ(1, argument_count); | 5446 ASSERT_EQ(1, argument_count); |
5457 PushArgumentsForStubCall(argument_count); | |
5458 HContext* context = new HContext; | 5447 HContext* context = new HContext; |
5459 AddInstruction(context); | 5448 AddInstruction(context); |
5460 HCallStub* result = | 5449 HCallStub* result = |
5461 new HCallStub(context, CodeStub::TranscendentalCache, argument_count); | 5450 new HCallStub(context, CodeStub::TranscendentalCache, argument_count); |
5462 result->set_transcendental_type(TranscendentalCache::COS); | 5451 result->set_transcendental_type(TranscendentalCache::COS); |
| 5452 PreProcessCall(result); |
5463 ast_context()->ReturnInstruction(result, ast_id); | 5453 ast_context()->ReturnInstruction(result, ast_id); |
5464 } | 5454 } |
5465 | 5455 |
5466 | 5456 |
5467 void HGraphBuilder::GenerateMathLog(int argument_count, int ast_id) { | 5457 void HGraphBuilder::GenerateMathLog(int argument_count, int ast_id) { |
5468 ASSERT_EQ(1, argument_count); | 5458 ASSERT_EQ(1, argument_count); |
5469 PushArgumentsForStubCall(argument_count); | |
5470 HContext* context = new HContext; | 5459 HContext* context = new HContext; |
5471 AddInstruction(context); | 5460 AddInstruction(context); |
5472 HCallStub* result = | 5461 HCallStub* result = |
5473 new HCallStub(context, CodeStub::TranscendentalCache, argument_count); | 5462 new HCallStub(context, CodeStub::TranscendentalCache, argument_count); |
5474 result->set_transcendental_type(TranscendentalCache::LOG); | 5463 result->set_transcendental_type(TranscendentalCache::LOG); |
| 5464 PreProcessCall(result); |
5475 ast_context()->ReturnInstruction(result, ast_id); | 5465 ast_context()->ReturnInstruction(result, ast_id); |
5476 } | 5466 } |
5477 | 5467 |
5478 | 5468 |
5479 void HGraphBuilder::GenerateMathSqrt(int argument_count, int ast_id) { | 5469 void HGraphBuilder::GenerateMathSqrt(int argument_count, int ast_id) { |
5480 BAILOUT("inlined runtime function: MathSqrt"); | 5470 BAILOUT("inlined runtime function: MathSqrt"); |
5481 } | 5471 } |
5482 | 5472 |
5483 | 5473 |
5484 // Check whether two RegExps are equivalent | 5474 // Check whether two RegExps are equivalent |
(...skipping 521 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
6006 } | 5996 } |
6007 } | 5997 } |
6008 | 5998 |
6009 #ifdef DEBUG | 5999 #ifdef DEBUG |
6010 if (graph_ != NULL) graph_->Verify(); | 6000 if (graph_ != NULL) graph_->Verify(); |
6011 if (allocator_ != NULL) allocator_->Verify(); | 6001 if (allocator_ != NULL) allocator_->Verify(); |
6012 #endif | 6002 #endif |
6013 } | 6003 } |
6014 | 6004 |
6015 } } // namespace v8::internal | 6005 } } // namespace v8::internal |
OLD | NEW |