| OLD | NEW |
| 1 // Copyright 2013 the V8 project authors. All rights reserved. | 1 // Copyright 2013 the V8 project authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "src/crankshaft/hydrogen.h" | 5 #include "src/crankshaft/hydrogen.h" |
| 6 | 6 |
| 7 #include <sstream> | 7 #include <sstream> |
| 8 | 8 |
| 9 #include "src/allocation-site-scopes.h" | 9 #include "src/allocation-site-scopes.h" |
| 10 #include "src/ast/ast-numbering.h" | 10 #include "src/ast/ast-numbering.h" |
| (...skipping 2209 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2220 return Pop(); | 2220 return Pop(); |
| 2221 } | 2221 } |
| 2222 | 2222 |
| 2223 HValue* HGraphBuilder::BuildToNumber(HValue* input) { | 2223 HValue* HGraphBuilder::BuildToNumber(HValue* input) { |
| 2224 if (input->type().IsTaggedNumber()) { | 2224 if (input->type().IsTaggedNumber()) { |
| 2225 return input; | 2225 return input; |
| 2226 } | 2226 } |
| 2227 Callable callable = CodeFactory::ToNumber(isolate()); | 2227 Callable callable = CodeFactory::ToNumber(isolate()); |
| 2228 HValue* stub = Add<HConstant>(callable.code()); | 2228 HValue* stub = Add<HConstant>(callable.code()); |
| 2229 HValue* values[] = {context(), input}; | 2229 HValue* values[] = {context(), input}; |
| 2230 HCallWithDescriptor* instr = | 2230 HCallWithDescriptor* instr = Add<HCallWithDescriptor>( |
| 2231 Add<HCallWithDescriptor>(stub, 0, callable.descriptor(), | 2231 stub, 0, callable.descriptor(), ArrayVector(values)); |
| 2232 Vector<HValue*>(values, arraysize(values))); | |
| 2233 instr->set_type(HType::TaggedNumber()); | 2232 instr->set_type(HType::TaggedNumber()); |
| 2234 return instr; | 2233 return instr; |
| 2235 } | 2234 } |
| 2236 | 2235 |
| 2237 | 2236 |
| 2238 HValue* HGraphBuilder::BuildToObject(HValue* receiver) { | 2237 HValue* HGraphBuilder::BuildToObject(HValue* receiver) { |
| 2239 NoObservableSideEffectsScope scope(this); | 2238 NoObservableSideEffectsScope scope(this); |
| 2240 | 2239 |
| 2241 // Create a joinable continuation. | 2240 // Create a joinable continuation. |
| 2242 HIfContinuation wrap(graph()->CreateBasicBlock(), | 2241 HIfContinuation wrap(graph()->CreateBasicBlock(), |
| (...skipping 3420 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5663 // Use the fast case closure allocation code that allocates in new | 5662 // Use the fast case closure allocation code that allocates in new |
| 5664 // space for nested functions that don't need literals cloning. | 5663 // space for nested functions that don't need literals cloning. |
| 5665 HConstant* shared_info_value = Add<HConstant>(shared_info); | 5664 HConstant* shared_info_value = Add<HConstant>(shared_info); |
| 5666 HInstruction* instr; | 5665 HInstruction* instr; |
| 5667 if (!expr->pretenure() && shared_info->num_literals() == 0) { | 5666 if (!expr->pretenure() && shared_info->num_literals() == 0) { |
| 5668 FastNewClosureStub stub(isolate(), shared_info->language_mode(), | 5667 FastNewClosureStub stub(isolate(), shared_info->language_mode(), |
| 5669 shared_info->kind()); | 5668 shared_info->kind()); |
| 5670 FastNewClosureDescriptor descriptor(isolate()); | 5669 FastNewClosureDescriptor descriptor(isolate()); |
| 5671 HValue* values[] = {context(), shared_info_value}; | 5670 HValue* values[] = {context(), shared_info_value}; |
| 5672 HConstant* stub_value = Add<HConstant>(stub.GetCode()); | 5671 HConstant* stub_value = Add<HConstant>(stub.GetCode()); |
| 5673 instr = New<HCallWithDescriptor>( | 5672 instr = New<HCallWithDescriptor>(stub_value, 0, descriptor, |
| 5674 stub_value, 0, descriptor, Vector<HValue*>(values, arraysize(values))); | 5673 ArrayVector(values)); |
| 5675 } else { | 5674 } else { |
| 5676 Add<HPushArguments>(shared_info_value); | 5675 Add<HPushArguments>(shared_info_value); |
| 5677 Runtime::FunctionId function_id = | 5676 Runtime::FunctionId function_id = |
| 5678 expr->pretenure() ? Runtime::kNewClosure_Tenured : Runtime::kNewClosure; | 5677 expr->pretenure() ? Runtime::kNewClosure_Tenured : Runtime::kNewClosure; |
| 5679 instr = New<HCallRuntime>(Runtime::FunctionForId(function_id), 1); | 5678 instr = New<HCallRuntime>(Runtime::FunctionForId(function_id), 1); |
| 5680 } | 5679 } |
| 5681 return ast_context()->ReturnInstruction(instr, expr->id()); | 5680 return ast_context()->ReturnInstruction(instr, expr->id()); |
| 5682 } | 5681 } |
| 5683 | 5682 |
| 5684 | 5683 |
| (...skipping 257 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5942 | 5941 |
| 5943 void HOptimizedGraphBuilder::VisitRegExpLiteral(RegExpLiteral* expr) { | 5942 void HOptimizedGraphBuilder::VisitRegExpLiteral(RegExpLiteral* expr) { |
| 5944 DCHECK(!HasStackOverflow()); | 5943 DCHECK(!HasStackOverflow()); |
| 5945 DCHECK(current_block() != NULL); | 5944 DCHECK(current_block() != NULL); |
| 5946 DCHECK(current_block()->HasPredecessor()); | 5945 DCHECK(current_block()->HasPredecessor()); |
| 5947 Callable callable = CodeFactory::FastCloneRegExp(isolate()); | 5946 Callable callable = CodeFactory::FastCloneRegExp(isolate()); |
| 5948 HValue* values[] = { | 5947 HValue* values[] = { |
| 5949 context(), AddThisFunction(), Add<HConstant>(expr->literal_index()), | 5948 context(), AddThisFunction(), Add<HConstant>(expr->literal_index()), |
| 5950 Add<HConstant>(expr->pattern()), Add<HConstant>(expr->flags())}; | 5949 Add<HConstant>(expr->pattern()), Add<HConstant>(expr->flags())}; |
| 5951 HConstant* stub_value = Add<HConstant>(callable.code()); | 5950 HConstant* stub_value = Add<HConstant>(callable.code()); |
| 5952 HInstruction* instr = | 5951 HInstruction* instr = New<HCallWithDescriptor>( |
| 5953 New<HCallWithDescriptor>(stub_value, 0, callable.descriptor(), | 5952 stub_value, 0, callable.descriptor(), ArrayVector(values)); |
| 5954 Vector<HValue*>(values, arraysize(values))); | |
| 5955 return ast_context()->ReturnInstruction(instr, expr->id()); | 5953 return ast_context()->ReturnInstruction(instr, expr->id()); |
| 5956 } | 5954 } |
| 5957 | 5955 |
| 5958 | 5956 |
| 5959 static bool CanInlinePropertyAccess(Handle<Map> map) { | 5957 static bool CanInlinePropertyAccess(Handle<Map> map) { |
| 5960 if (map->instance_type() == HEAP_NUMBER_TYPE) return true; | 5958 if (map->instance_type() == HEAP_NUMBER_TYPE) return true; |
| 5961 if (map->instance_type() < FIRST_NONSTRING_TYPE) return true; | 5959 if (map->instance_type() < FIRST_NONSTRING_TYPE) return true; |
| 5962 return map->IsJSObjectMap() && !map->is_dictionary_map() && | 5960 return map->IsJSObjectMap() && !map->is_dictionary_map() && |
| 5963 !map->has_named_interceptor() && | 5961 !map->has_named_interceptor() && |
| 5964 // TODO(verwaest): Whitelist contexts to which we have access. | 5962 // TODO(verwaest): Whitelist contexts to which we have access. |
| (...skipping 2201 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 8166 } | 8164 } |
| 8167 HValue* arity = Add<HConstant>(argument_count - 1); | 8165 HValue* arity = Add<HConstant>(argument_count - 1); |
| 8168 | 8166 |
| 8169 HValue* op_vals[] = {context(), function, arity}; | 8167 HValue* op_vals[] = {context(), function, arity}; |
| 8170 | 8168 |
| 8171 Callable callable = | 8169 Callable callable = |
| 8172 CodeFactory::Call(isolate(), convert_mode, tail_call_mode); | 8170 CodeFactory::Call(isolate(), convert_mode, tail_call_mode); |
| 8173 HConstant* stub = Add<HConstant>(callable.code()); | 8171 HConstant* stub = Add<HConstant>(callable.code()); |
| 8174 | 8172 |
| 8175 return New<HCallWithDescriptor>(stub, argument_count, callable.descriptor(), | 8173 return New<HCallWithDescriptor>(stub, argument_count, callable.descriptor(), |
| 8176 Vector<HValue*>(op_vals, arraysize(op_vals)), | 8174 ArrayVector(op_vals), |
| 8177 syntactic_tail_call_mode); | 8175 syntactic_tail_call_mode); |
| 8178 } | 8176 } |
| 8179 | 8177 |
| 8180 HInstruction* HOptimizedGraphBuilder::NewCallFunctionViaIC( | 8178 HInstruction* HOptimizedGraphBuilder::NewCallFunctionViaIC( |
| 8181 HValue* function, int argument_count, TailCallMode syntactic_tail_call_mode, | 8179 HValue* function, int argument_count, TailCallMode syntactic_tail_call_mode, |
| 8182 ConvertReceiverMode convert_mode, TailCallMode tail_call_mode, | 8180 ConvertReceiverMode convert_mode, TailCallMode tail_call_mode, |
| 8183 FeedbackVectorSlot slot) { | 8181 FeedbackVectorSlot slot) { |
| 8184 if (syntactic_tail_call_mode == TailCallMode::kAllow) { | 8182 if (syntactic_tail_call_mode == TailCallMode::kAllow) { |
| 8185 BuildEnsureCallable(function); | 8183 BuildEnsureCallable(function); |
| 8186 } else { | 8184 } else { |
| 8187 DCHECK_EQ(TailCallMode::kDisallow, tail_call_mode); | 8185 DCHECK_EQ(TailCallMode::kDisallow, tail_call_mode); |
| 8188 } | 8186 } |
| 8189 int arity = argument_count - 1; | 8187 int arity = argument_count - 1; |
| 8190 Handle<TypeFeedbackVector> vector(current_feedback_vector(), isolate()); | 8188 Handle<TypeFeedbackVector> vector(current_feedback_vector(), isolate()); |
| 8191 HValue* index_val = Add<HConstant>(vector->GetIndex(slot)); | 8189 HValue* index_val = Add<HConstant>(vector->GetIndex(slot)); |
| 8192 HValue* vector_val = Add<HConstant>(vector); | 8190 HValue* vector_val = Add<HConstant>(vector); |
| 8193 | 8191 |
| 8194 HValue* op_vals[] = {context(), function, index_val, vector_val}; | 8192 HValue* op_vals[] = {context(), function, index_val, vector_val}; |
| 8195 | 8193 |
| 8196 Callable callable = CodeFactory::CallICInOptimizedCode( | 8194 Callable callable = CodeFactory::CallICInOptimizedCode( |
| 8197 isolate(), arity, convert_mode, tail_call_mode); | 8195 isolate(), arity, convert_mode, tail_call_mode); |
| 8198 HConstant* stub = Add<HConstant>(callable.code()); | 8196 HConstant* stub = Add<HConstant>(callable.code()); |
| 8199 | 8197 |
| 8200 return New<HCallWithDescriptor>(stub, argument_count, callable.descriptor(), | 8198 return New<HCallWithDescriptor>(stub, argument_count, callable.descriptor(), |
| 8201 Vector<HValue*>(op_vals, arraysize(op_vals)), | 8199 ArrayVector(op_vals), |
| 8202 syntactic_tail_call_mode); | 8200 syntactic_tail_call_mode); |
| 8203 } | 8201 } |
| 8204 | 8202 |
| 8205 HInstruction* HOptimizedGraphBuilder::NewCallConstantFunction( | 8203 HInstruction* HOptimizedGraphBuilder::NewCallConstantFunction( |
| 8206 Handle<JSFunction> function, int argument_count, | 8204 Handle<JSFunction> function, int argument_count, |
| 8207 TailCallMode syntactic_tail_call_mode, TailCallMode tail_call_mode) { | 8205 TailCallMode syntactic_tail_call_mode, TailCallMode tail_call_mode) { |
| 8208 HValue* target = Add<HConstant>(function); | 8206 HValue* target = Add<HConstant>(function); |
| 8209 return New<HInvokeFunction>(target, function, argument_count, | 8207 return New<HInvokeFunction>(target, function, argument_count, |
| 8210 syntactic_tail_call_mode, tail_call_mode); | 8208 syntactic_tail_call_mode, tail_call_mode); |
| 8211 } | 8209 } |
| (...skipping 2018 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 10230 // The constructor function is both an operand to the instruction and an | 10228 // The constructor function is both an operand to the instruction and an |
| 10231 // argument to the construct call. | 10229 // argument to the construct call. |
| 10232 if (TryHandleArrayCallNew(expr, function)) return; | 10230 if (TryHandleArrayCallNew(expr, function)) return; |
| 10233 } | 10231 } |
| 10234 | 10232 |
| 10235 HValue* arity = Add<HConstant>(argument_count - 1); | 10233 HValue* arity = Add<HConstant>(argument_count - 1); |
| 10236 HValue* op_vals[] = {context(), function, function, arity}; | 10234 HValue* op_vals[] = {context(), function, function, arity}; |
| 10237 Callable callable = CodeFactory::Construct(isolate()); | 10235 Callable callable = CodeFactory::Construct(isolate()); |
| 10238 HConstant* stub = Add<HConstant>(callable.code()); | 10236 HConstant* stub = Add<HConstant>(callable.code()); |
| 10239 PushArgumentsFromEnvironment(argument_count); | 10237 PushArgumentsFromEnvironment(argument_count); |
| 10240 HInstruction* construct = | 10238 HInstruction* construct = New<HCallWithDescriptor>( |
| 10241 New<HCallWithDescriptor>(stub, argument_count, callable.descriptor(), | 10239 stub, argument_count, callable.descriptor(), ArrayVector(op_vals)); |
| 10242 Vector<HValue*>(op_vals, arraysize(op_vals))); | |
| 10243 return ast_context()->ReturnInstruction(construct, expr->id()); | 10240 return ast_context()->ReturnInstruction(construct, expr->id()); |
| 10244 } | 10241 } |
| 10245 | 10242 |
| 10246 | 10243 |
| 10247 void HOptimizedGraphBuilder::BuildInitializeInobjectProperties( | 10244 void HOptimizedGraphBuilder::BuildInitializeInobjectProperties( |
| 10248 HValue* receiver, Handle<Map> initial_map) { | 10245 HValue* receiver, Handle<Map> initial_map) { |
| 10249 if (initial_map->GetInObjectProperties() != 0) { | 10246 if (initial_map->GetInObjectProperties() != 0) { |
| 10250 HConstant* undefined = graph()->GetConstantUndefined(); | 10247 HConstant* undefined = graph()->GetConstantUndefined(); |
| 10251 for (int i = 0; i < initial_map->GetInObjectProperties(); i++) { | 10248 for (int i = 0; i < initial_map->GetInObjectProperties(); i++) { |
| 10252 int property_offset = initial_map->GetInObjectPropertyOffset(i); | 10249 int property_offset = initial_map->GetInObjectPropertyOffset(i); |
| (...skipping 1046 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 11299 | 11296 |
| 11300 bool is_non_primitive = (left_rep.IsTagged() && !left_rep.IsSmi()) || | 11297 bool is_non_primitive = (left_rep.IsTagged() && !left_rep.IsSmi()) || |
| 11301 (right_rep.IsTagged() && !right_rep.IsSmi()); | 11298 (right_rep.IsTagged() && !right_rep.IsSmi()); |
| 11302 | 11299 |
| 11303 HInstruction* instr = NULL; | 11300 HInstruction* instr = NULL; |
| 11304 // Only the stub is allowed to call into the runtime, since otherwise we would | 11301 // Only the stub is allowed to call into the runtime, since otherwise we would |
| 11305 // inline several instructions (including the two pushes) for every tagged | 11302 // inline several instructions (including the two pushes) for every tagged |
| 11306 // operation in optimized code, which is more expensive, than a stub call. | 11303 // operation in optimized code, which is more expensive, than a stub call. |
| 11307 if (graph()->info()->IsStub() && is_non_primitive) { | 11304 if (graph()->info()->IsStub() && is_non_primitive) { |
| 11308 HValue* values[] = {context(), left, right}; | 11305 HValue* values[] = {context(), left, right}; |
| 11309 #define GET_STUB(Name) \ | 11306 #define GET_STUB(Name) \ |
| 11310 do { \ | 11307 do { \ |
| 11311 Callable callable = CodeFactory::Name(isolate()); \ | 11308 Callable callable = CodeFactory::Name(isolate()); \ |
| 11312 HValue* stub = Add<HConstant>(callable.code()); \ | 11309 HValue* stub = Add<HConstant>(callable.code()); \ |
| 11313 instr = AddUncasted<HCallWithDescriptor>( \ | 11310 instr = AddUncasted<HCallWithDescriptor>(stub, 0, callable.descriptor(), \ |
| 11314 stub, 0, callable.descriptor(), \ | 11311 ArrayVector(values)); \ |
| 11315 Vector<HValue*>(values, arraysize(values))); \ | |
| 11316 } while (false) | 11312 } while (false) |
| 11317 | 11313 |
| 11318 switch (op) { | 11314 switch (op) { |
| 11319 default: | 11315 default: |
| 11320 UNREACHABLE(); | 11316 UNREACHABLE(); |
| 11321 case Token::ADD: | 11317 case Token::ADD: |
| 11322 GET_STUB(Add); | 11318 GET_STUB(Add); |
| 11323 break; | 11319 break; |
| 11324 case Token::SUB: | 11320 case Token::SUB: |
| 11325 GET_STUB(Subtract); | 11321 GET_STUB(Subtract); |
| (...skipping 1112 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 12438 void HOptimizedGraphBuilder::GenerateToInteger(CallRuntime* call) { | 12434 void HOptimizedGraphBuilder::GenerateToInteger(CallRuntime* call) { |
| 12439 DCHECK_EQ(1, call->arguments()->length()); | 12435 DCHECK_EQ(1, call->arguments()->length()); |
| 12440 CHECK_ALIVE(VisitForValue(call->arguments()->at(0))); | 12436 CHECK_ALIVE(VisitForValue(call->arguments()->at(0))); |
| 12441 HValue* input = Pop(); | 12437 HValue* input = Pop(); |
| 12442 if (input->type().IsSmi()) { | 12438 if (input->type().IsSmi()) { |
| 12443 return ast_context()->ReturnValue(input); | 12439 return ast_context()->ReturnValue(input); |
| 12444 } else { | 12440 } else { |
| 12445 Callable callable = CodeFactory::ToInteger(isolate()); | 12441 Callable callable = CodeFactory::ToInteger(isolate()); |
| 12446 HValue* stub = Add<HConstant>(callable.code()); | 12442 HValue* stub = Add<HConstant>(callable.code()); |
| 12447 HValue* values[] = {context(), input}; | 12443 HValue* values[] = {context(), input}; |
| 12448 HInstruction* result = | 12444 HInstruction* result = New<HCallWithDescriptor>( |
| 12449 New<HCallWithDescriptor>(stub, 0, callable.descriptor(), | 12445 stub, 0, callable.descriptor(), ArrayVector(values)); |
| 12450 Vector<HValue*>(values, arraysize(values))); | |
| 12451 return ast_context()->ReturnInstruction(result, call->id()); | 12446 return ast_context()->ReturnInstruction(result, call->id()); |
| 12452 } | 12447 } |
| 12453 } | 12448 } |
| 12454 | 12449 |
| 12455 | 12450 |
| 12456 void HOptimizedGraphBuilder::GenerateToName(CallRuntime* call) { | 12451 void HOptimizedGraphBuilder::GenerateToName(CallRuntime* call) { |
| 12457 DCHECK_EQ(1, call->arguments()->length()); | 12452 DCHECK_EQ(1, call->arguments()->length()); |
| 12458 CHECK_ALIVE(VisitForValue(call->arguments()->at(0))); | 12453 CHECK_ALIVE(VisitForValue(call->arguments()->at(0))); |
| 12459 HValue* input = Pop(); | 12454 HValue* input = Pop(); |
| 12460 if (input->type().IsSmi()) { | 12455 if (input->type().IsSmi()) { |
| 12461 HValue* result = BuildNumberToString(input, Type::SignedSmall()); | 12456 HValue* result = BuildNumberToString(input, Type::SignedSmall()); |
| 12462 return ast_context()->ReturnValue(result); | 12457 return ast_context()->ReturnValue(result); |
| 12463 } else if (input->type().IsTaggedNumber()) { | 12458 } else if (input->type().IsTaggedNumber()) { |
| 12464 HValue* result = BuildNumberToString(input, Type::Number()); | 12459 HValue* result = BuildNumberToString(input, Type::Number()); |
| 12465 return ast_context()->ReturnValue(result); | 12460 return ast_context()->ReturnValue(result); |
| 12466 } else if (input->type().IsString()) { | 12461 } else if (input->type().IsString()) { |
| 12467 return ast_context()->ReturnValue(input); | 12462 return ast_context()->ReturnValue(input); |
| 12468 } else { | 12463 } else { |
| 12469 Callable callable = CodeFactory::ToName(isolate()); | 12464 Callable callable = CodeFactory::ToName(isolate()); |
| 12470 HValue* stub = Add<HConstant>(callable.code()); | 12465 HValue* stub = Add<HConstant>(callable.code()); |
| 12471 HValue* values[] = {context(), input}; | 12466 HValue* values[] = {context(), input}; |
| 12472 HInstruction* result = | 12467 HInstruction* result = New<HCallWithDescriptor>( |
| 12473 New<HCallWithDescriptor>(stub, 0, callable.descriptor(), | 12468 stub, 0, callable.descriptor(), ArrayVector(values)); |
| 12474 Vector<HValue*>(values, arraysize(values))); | |
| 12475 return ast_context()->ReturnInstruction(result, call->id()); | 12469 return ast_context()->ReturnInstruction(result, call->id()); |
| 12476 } | 12470 } |
| 12477 } | 12471 } |
| 12478 | 12472 |
| 12479 | 12473 |
| 12480 void HOptimizedGraphBuilder::GenerateToObject(CallRuntime* call) { | 12474 void HOptimizedGraphBuilder::GenerateToObject(CallRuntime* call) { |
| 12481 DCHECK_EQ(1, call->arguments()->length()); | 12475 DCHECK_EQ(1, call->arguments()->length()); |
| 12482 CHECK_ALIVE(VisitForValue(call->arguments()->at(0))); | 12476 CHECK_ALIVE(VisitForValue(call->arguments()->at(0))); |
| 12483 HValue* value = Pop(); | 12477 HValue* value = Pop(); |
| 12484 HValue* result = BuildToObject(value); | 12478 HValue* result = BuildToObject(value); |
| 12485 return ast_context()->ReturnValue(result); | 12479 return ast_context()->ReturnValue(result); |
| 12486 } | 12480 } |
| 12487 | 12481 |
| 12488 | 12482 |
| 12489 void HOptimizedGraphBuilder::GenerateToString(CallRuntime* call) { | 12483 void HOptimizedGraphBuilder::GenerateToString(CallRuntime* call) { |
| 12490 DCHECK_EQ(1, call->arguments()->length()); | 12484 DCHECK_EQ(1, call->arguments()->length()); |
| 12491 CHECK_ALIVE(VisitForValue(call->arguments()->at(0))); | 12485 CHECK_ALIVE(VisitForValue(call->arguments()->at(0))); |
| 12492 HValue* input = Pop(); | 12486 HValue* input = Pop(); |
| 12493 if (input->type().IsString()) { | 12487 if (input->type().IsString()) { |
| 12494 return ast_context()->ReturnValue(input); | 12488 return ast_context()->ReturnValue(input); |
| 12495 } else { | 12489 } else { |
| 12496 Callable callable = CodeFactory::ToString(isolate()); | 12490 Callable callable = CodeFactory::ToString(isolate()); |
| 12497 HValue* stub = Add<HConstant>(callable.code()); | 12491 HValue* stub = Add<HConstant>(callable.code()); |
| 12498 HValue* values[] = {context(), input}; | 12492 HValue* values[] = {context(), input}; |
| 12499 HInstruction* result = | 12493 HInstruction* result = New<HCallWithDescriptor>( |
| 12500 New<HCallWithDescriptor>(stub, 0, callable.descriptor(), | 12494 stub, 0, callable.descriptor(), ArrayVector(values)); |
| 12501 Vector<HValue*>(values, arraysize(values))); | |
| 12502 return ast_context()->ReturnInstruction(result, call->id()); | 12495 return ast_context()->ReturnInstruction(result, call->id()); |
| 12503 } | 12496 } |
| 12504 } | 12497 } |
| 12505 | 12498 |
| 12506 | 12499 |
| 12507 void HOptimizedGraphBuilder::GenerateToLength(CallRuntime* call) { | 12500 void HOptimizedGraphBuilder::GenerateToLength(CallRuntime* call) { |
| 12508 DCHECK_EQ(1, call->arguments()->length()); | 12501 DCHECK_EQ(1, call->arguments()->length()); |
| 12509 CHECK_ALIVE(VisitForValue(call->arguments()->at(0))); | 12502 CHECK_ALIVE(VisitForValue(call->arguments()->at(0))); |
| 12510 Callable callable = CodeFactory::ToLength(isolate()); | 12503 Callable callable = CodeFactory::ToLength(isolate()); |
| 12511 HValue* input = Pop(); | 12504 HValue* input = Pop(); |
| 12512 HValue* stub = Add<HConstant>(callable.code()); | 12505 HValue* stub = Add<HConstant>(callable.code()); |
| 12513 HValue* values[] = {context(), input}; | 12506 HValue* values[] = {context(), input}; |
| 12514 HInstruction* result = | 12507 HInstruction* result = New<HCallWithDescriptor>( |
| 12515 New<HCallWithDescriptor>(stub, 0, callable.descriptor(), | 12508 stub, 0, callable.descriptor(), ArrayVector(values)); |
| 12516 Vector<HValue*>(values, arraysize(values))); | |
| 12517 return ast_context()->ReturnInstruction(result, call->id()); | 12509 return ast_context()->ReturnInstruction(result, call->id()); |
| 12518 } | 12510 } |
| 12519 | 12511 |
| 12520 | 12512 |
| 12521 void HOptimizedGraphBuilder::GenerateToNumber(CallRuntime* call) { | 12513 void HOptimizedGraphBuilder::GenerateToNumber(CallRuntime* call) { |
| 12522 DCHECK_EQ(1, call->arguments()->length()); | 12514 DCHECK_EQ(1, call->arguments()->length()); |
| 12523 CHECK_ALIVE(VisitForValue(call->arguments()->at(0))); | 12515 CHECK_ALIVE(VisitForValue(call->arguments()->at(0))); |
| 12524 Callable callable = CodeFactory::ToNumber(isolate()); | 12516 Callable callable = CodeFactory::ToNumber(isolate()); |
| 12525 HValue* input = Pop(); | 12517 HValue* input = Pop(); |
| 12526 HValue* result = BuildToNumber(input); | 12518 HValue* result = BuildToNumber(input); |
| (...skipping 152 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 12679 | 12671 |
| 12680 | 12672 |
| 12681 // Fast support for SubString. | 12673 // Fast support for SubString. |
| 12682 void HOptimizedGraphBuilder::GenerateSubString(CallRuntime* call) { | 12674 void HOptimizedGraphBuilder::GenerateSubString(CallRuntime* call) { |
| 12683 DCHECK_EQ(3, call->arguments()->length()); | 12675 DCHECK_EQ(3, call->arguments()->length()); |
| 12684 CHECK_ALIVE(VisitExpressions(call->arguments())); | 12676 CHECK_ALIVE(VisitExpressions(call->arguments())); |
| 12685 PushArgumentsFromEnvironment(call->arguments()->length()); | 12677 PushArgumentsFromEnvironment(call->arguments()->length()); |
| 12686 Callable callable = CodeFactory::SubString(isolate()); | 12678 Callable callable = CodeFactory::SubString(isolate()); |
| 12687 HValue* stub = Add<HConstant>(callable.code()); | 12679 HValue* stub = Add<HConstant>(callable.code()); |
| 12688 HValue* values[] = {context()}; | 12680 HValue* values[] = {context()}; |
| 12689 HInstruction* result = New<HCallWithDescriptor>( | 12681 HInstruction* result = |
| 12690 stub, call->arguments()->length(), callable.descriptor(), | 12682 New<HCallWithDescriptor>(stub, call->arguments()->length(), |
| 12691 Vector<HValue*>(values, arraysize(values))); | 12683 callable.descriptor(), ArrayVector(values)); |
| 12692 result->set_type(HType::String()); | 12684 result->set_type(HType::String()); |
| 12693 return ast_context()->ReturnInstruction(result, call->id()); | 12685 return ast_context()->ReturnInstruction(result, call->id()); |
| 12694 } | 12686 } |
| 12695 | 12687 |
| 12696 // Support for direct creation of new objects. | 12688 // Support for direct creation of new objects. |
| 12697 void HOptimizedGraphBuilder::GenerateNewObject(CallRuntime* call) { | 12689 void HOptimizedGraphBuilder::GenerateNewObject(CallRuntime* call) { |
| 12698 DCHECK_EQ(2, call->arguments()->length()); | 12690 DCHECK_EQ(2, call->arguments()->length()); |
| 12699 CHECK_ALIVE(VisitExpressions(call->arguments())); | 12691 CHECK_ALIVE(VisitExpressions(call->arguments())); |
| 12700 FastNewObjectStub stub(isolate()); | 12692 FastNewObjectStub stub(isolate()); |
| 12701 FastNewObjectDescriptor descriptor(isolate()); | 12693 FastNewObjectDescriptor descriptor(isolate()); |
| 12702 HValue* values[] = {context(), Pop(), Pop()}; | 12694 HValue* values[] = {context(), Pop(), Pop()}; |
| 12703 HConstant* stub_value = Add<HConstant>(stub.GetCode()); | 12695 HConstant* stub_value = Add<HConstant>(stub.GetCode()); |
| 12704 HInstruction* result = New<HCallWithDescriptor>( | 12696 HInstruction* result = |
| 12705 stub_value, 0, descriptor, Vector<HValue*>(values, arraysize(values))); | 12697 New<HCallWithDescriptor>(stub_value, 0, descriptor, ArrayVector(values)); |
| 12706 return ast_context()->ReturnInstruction(result, call->id()); | 12698 return ast_context()->ReturnInstruction(result, call->id()); |
| 12707 } | 12699 } |
| 12708 | 12700 |
| 12709 // Support for direct calls from JavaScript to native RegExp code. | 12701 // Support for direct calls from JavaScript to native RegExp code. |
| 12710 void HOptimizedGraphBuilder::GenerateRegExpExec(CallRuntime* call) { | 12702 void HOptimizedGraphBuilder::GenerateRegExpExec(CallRuntime* call) { |
| 12711 DCHECK_EQ(4, call->arguments()->length()); | 12703 DCHECK_EQ(4, call->arguments()->length()); |
| 12712 CHECK_ALIVE(VisitExpressions(call->arguments())); | 12704 CHECK_ALIVE(VisitExpressions(call->arguments())); |
| 12713 PushArgumentsFromEnvironment(call->arguments()->length()); | 12705 PushArgumentsFromEnvironment(call->arguments()->length()); |
| 12714 Callable callable = CodeFactory::RegExpExec(isolate()); | 12706 Callable callable = CodeFactory::RegExpExec(isolate()); |
| 12715 HValue* stub = Add<HConstant>(callable.code()); | 12707 HValue* stub = Add<HConstant>(callable.code()); |
| 12716 HValue* values[] = {context()}; | 12708 HValue* values[] = {context()}; |
| 12717 HInstruction* result = New<HCallWithDescriptor>( | 12709 HInstruction* result = |
| 12718 stub, call->arguments()->length(), callable.descriptor(), | 12710 New<HCallWithDescriptor>(stub, call->arguments()->length(), |
| 12719 Vector<HValue*>(values, arraysize(values))); | 12711 callable.descriptor(), ArrayVector(values)); |
| 12720 return ast_context()->ReturnInstruction(result, call->id()); | 12712 return ast_context()->ReturnInstruction(result, call->id()); |
| 12721 } | 12713 } |
| 12722 | 12714 |
| 12723 | 12715 |
| 12724 void HOptimizedGraphBuilder::GenerateRegExpFlags(CallRuntime* call) { | 12716 void HOptimizedGraphBuilder::GenerateRegExpFlags(CallRuntime* call) { |
| 12725 DCHECK_EQ(1, call->arguments()->length()); | 12717 DCHECK_EQ(1, call->arguments()->length()); |
| 12726 CHECK_ALIVE(VisitExpressions(call->arguments())); | 12718 CHECK_ALIVE(VisitExpressions(call->arguments())); |
| 12727 HValue* regexp = Pop(); | 12719 HValue* regexp = Pop(); |
| 12728 HInstruction* result = | 12720 HInstruction* result = |
| 12729 New<HLoadNamedField>(regexp, nullptr, HObjectAccess::ForJSRegExpFlags()); | 12721 New<HLoadNamedField>(regexp, nullptr, HObjectAccess::ForJSRegExpFlags()); |
| (...skipping 106 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 12836 } | 12828 } |
| 12837 } | 12829 } |
| 12838 } | 12830 } |
| 12839 | 12831 |
| 12840 CallTrampolineDescriptor descriptor(isolate()); | 12832 CallTrampolineDescriptor descriptor(isolate()); |
| 12841 PushArgumentsFromEnvironment(call->arguments()->length() - 1); | 12833 PushArgumentsFromEnvironment(call->arguments()->length() - 1); |
| 12842 HValue* trampoline = Add<HConstant>(isolate()->builtins()->Call()); | 12834 HValue* trampoline = Add<HConstant>(isolate()->builtins()->Call()); |
| 12843 HValue* target = Pop(); | 12835 HValue* target = Pop(); |
| 12844 HValue* values[] = {context(), target, | 12836 HValue* values[] = {context(), target, |
| 12845 Add<HConstant>(call->arguments()->length() - 2)}; | 12837 Add<HConstant>(call->arguments()->length() - 2)}; |
| 12846 HInstruction* result = New<HCallWithDescriptor>( | 12838 HInstruction* result = |
| 12847 trampoline, call->arguments()->length() - 1, descriptor, | 12839 New<HCallWithDescriptor>(trampoline, call->arguments()->length() - 1, |
| 12848 Vector<HValue*>(values, arraysize(values))); | 12840 descriptor, ArrayVector(values)); |
| 12849 return ast_context()->ReturnInstruction(result, call->id()); | 12841 return ast_context()->ReturnInstruction(result, call->id()); |
| 12850 } | 12842 } |
| 12851 | 12843 |
| 12852 | 12844 |
| 12853 // Fast call to math functions. | 12845 // Fast call to math functions. |
| 12854 void HOptimizedGraphBuilder::GenerateMathPow(CallRuntime* call) { | 12846 void HOptimizedGraphBuilder::GenerateMathPow(CallRuntime* call) { |
| 12855 DCHECK_EQ(2, call->arguments()->length()); | 12847 DCHECK_EQ(2, call->arguments()->length()); |
| 12856 CHECK_ALIVE(VisitForValue(call->arguments()->at(0))); | 12848 CHECK_ALIVE(VisitForValue(call->arguments()->at(0))); |
| 12857 CHECK_ALIVE(VisitForValue(call->arguments()->at(1))); | 12849 CHECK_ALIVE(VisitForValue(call->arguments()->at(1))); |
| 12858 HValue* right = Pop(); | 12850 HValue* right = Pop(); |
| (...skipping 870 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 13729 isolate()->GetHTracer()->TraceHydrogen(name(), graph_); | 13721 isolate()->GetHTracer()->TraceHydrogen(name(), graph_); |
| 13730 } | 13722 } |
| 13731 | 13723 |
| 13732 #ifdef DEBUG | 13724 #ifdef DEBUG |
| 13733 graph_->Verify(false); // No full verify. | 13725 graph_->Verify(false); // No full verify. |
| 13734 #endif | 13726 #endif |
| 13735 } | 13727 } |
| 13736 | 13728 |
| 13737 } // namespace internal | 13729 } // namespace internal |
| 13738 } // namespace v8 | 13730 } // namespace v8 |
| OLD | NEW |