Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright 2014 the V8 project authors. All rights reserved. | 1 // Copyright 2014 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/code-factory.h" | 5 #include "src/code-factory.h" |
| 6 #include "src/code-stubs.h" | 6 #include "src/code-stubs.h" |
| 7 #include "src/compiler/common-operator.h" | 7 #include "src/compiler/common-operator.h" |
| 8 #include "src/compiler/graph-inl.h" | 8 #include "src/compiler/graph-inl.h" |
| 9 #include "src/compiler/js-generic-lowering.h" | 9 #include "src/compiler/js-generic-lowering.h" |
| 10 #include "src/compiler/machine-operator.h" | 10 #include "src/compiler/machine-operator.h" |
| 11 #include "src/compiler/node-aux-data-inl.h" | 11 #include "src/compiler/node-aux-data-inl.h" |
| 12 #include "src/compiler/node-matchers.h" | |
| 12 #include "src/compiler/node-properties-inl.h" | 13 #include "src/compiler/node-properties-inl.h" |
| 13 #include "src/unique.h" | 14 #include "src/unique.h" |
| 14 | 15 |
| 15 namespace v8 { | 16 namespace v8 { |
| 16 namespace internal { | 17 namespace internal { |
| 17 namespace compiler { | 18 namespace compiler { |
| 18 | 19 |
| 19 JSGenericLowering::JSGenericLowering(CompilationInfo* info, JSGraph* jsgraph) | 20 JSGenericLowering::JSGenericLowering(CompilationInfo* info, JSGraph* jsgraph) |
| 20 : info_(info), | 21 : info_(info), |
| 21 jsgraph_(jsgraph), | 22 jsgraph_(jsgraph), |
| (...skipping 376 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 398 Node* stub_code = CodeConstant(stub.GetCode()); | 399 Node* stub_code = CodeConstant(stub.GetCode()); |
| 399 Node* construct = NodeProperties::GetValueInput(node, 0); | 400 Node* construct = NodeProperties::GetValueInput(node, 0); |
| 400 PatchInsertInput(node, 0, stub_code); | 401 PatchInsertInput(node, 0, stub_code); |
| 401 PatchInsertInput(node, 1, Int32Constant(arity - 1)); | 402 PatchInsertInput(node, 1, Int32Constant(arity - 1)); |
| 402 PatchInsertInput(node, 2, construct); | 403 PatchInsertInput(node, 2, construct); |
| 403 PatchInsertInput(node, 3, jsgraph()->UndefinedConstant()); | 404 PatchInsertInput(node, 3, jsgraph()->UndefinedConstant()); |
| 404 PatchOperator(node, common()->Call(desc)); | 405 PatchOperator(node, common()->Call(desc)); |
| 405 } | 406 } |
| 406 | 407 |
| 407 | 408 |
| 409 bool JSGenericLowering::TryLowerDirectJSCall(Node* node) { | |
| 410 // Lower to a direct call to a constant JSFunction if legal. | |
| 411 const CallFunctionParameters& p = CallFunctionParametersOf(node->op()); | |
| 412 int arg_count = static_cast<int>(p.arity() - 2); | |
| 413 | |
| 414 // Check the function is a constant and is really a JSFunction. | |
| 415 HeapObjectMatcher<Object> function_const(node->InputAt(0)); | |
| 416 if (!function_const.HasValue()) return false; // not a constant. | |
| 417 Handle<Object> func = function_const.Value().handle(); | |
| 418 if (!func->IsJSFunction()) return false; // not a function. | |
| 419 Handle<JSFunction> function = Handle<JSFunction>::cast(func); | |
| 420 if (arg_count != function->shared()->formal_parameter_count()) return false; | |
| 421 | |
| 422 // Check the receiver doesn't need to be wrapped. | |
| 423 Node* receiver = node->InputAt(1); | |
| 424 if (!NodeProperties::IsTyped(receiver)) return false; | |
| 425 Type* ok_receiver = Type::Union(Type::Undefined(), Type::Receiver(), zone()); | |
| 426 if (!NodeProperties::GetBounds(receiver).upper->Is(ok_receiver)) return false; | |
| 427 | |
| 428 int index = NodeProperties::FirstContextIndex(node); | |
| 429 | |
| 430 // TODO(titzer): total hack to share function context constants. | |
| 431 // Remove this when the JSGraph canonicalizes heap constants. | |
| 432 Node* context = node->InputAt(index); | |
| 433 HeapObjectMatcher<Context> context_const(context); | |
| 434 if (!context_const.HasValue() || | |
| 435 *(context_const.Value().handle()) != function->context()) { | |
| 436 context = jsgraph()->HeapConstant(Handle<Context>(function->context())); | |
| 437 } | |
| 438 node->ReplaceInput(index, context); | |
| 439 CallDescriptor* desc = linkage()->GetJSCallDescriptor( | |
| 440 1 + arg_count, jsgraph()->zone(), FlagsForNode(node)); | |
| 441 PatchOperator(node, common()->Call(desc)); | |
| 442 return true; | |
| 443 } | |
| 444 | |
| 445 | |
| 408 void JSGenericLowering::LowerJSCallFunction(Node* node) { | 446 void JSGenericLowering::LowerJSCallFunction(Node* node) { |
| 409 const CallFunctionParameters& p = CallFunctionParametersOf(node->op()); | 447 if (!TryLowerDirectJSCall(node)) { |
|
Michael Starzinger
2014/11/03 09:57:41
nit: How would you feel about an early return here
| |
| 410 CallFunctionStub stub(isolate(), static_cast<int>(p.arity() - 2), p.flags()); | 448 // Call to computed function; use CallFunctionStub; |
| 411 CallInterfaceDescriptor d = stub.GetCallInterfaceDescriptor(); | 449 const CallFunctionParameters& p = CallFunctionParametersOf(node->op()); |
| 412 CallDescriptor* desc = linkage()->GetStubCallDescriptor( | 450 int arg_count = static_cast<int>(p.arity() - 2); |
| 413 d, static_cast<int>(p.arity() - 1), FlagsForNode(node)); | 451 CallFunctionStub stub(isolate(), arg_count, p.flags()); |
| 414 Node* stub_code = CodeConstant(stub.GetCode()); | 452 CallInterfaceDescriptor d = stub.GetCallInterfaceDescriptor(); |
| 415 PatchInsertInput(node, 0, stub_code); | 453 CallDescriptor* desc = linkage()->GetStubCallDescriptor( |
| 416 PatchOperator(node, common()->Call(desc)); | 454 d, static_cast<int>(p.arity() - 1), FlagsForNode(node)); |
| 455 Node* stub_code = CodeConstant(stub.GetCode()); | |
| 456 PatchInsertInput(node, 0, stub_code); | |
| 457 PatchOperator(node, common()->Call(desc)); | |
| 458 } | |
| 417 } | 459 } |
| 418 | 460 |
| 419 | 461 |
| 420 void JSGenericLowering::LowerJSCallRuntime(Node* node) { | 462 void JSGenericLowering::LowerJSCallRuntime(Node* node) { |
| 421 const CallRuntimeParameters& p = CallRuntimeParametersOf(node->op()); | 463 const CallRuntimeParameters& p = CallRuntimeParametersOf(node->op()); |
| 422 ReplaceWithRuntimeCall(node, p.id(), static_cast<int>(p.arity())); | 464 ReplaceWithRuntimeCall(node, p.id(), static_cast<int>(p.arity())); |
| 423 } | 465 } |
| 424 | 466 |
| 425 } // namespace compiler | 467 } // namespace compiler |
| 426 } // namespace internal | 468 } // namespace internal |
| 427 } // namespace v8 | 469 } // namespace v8 |
| OLD | NEW |