| 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/js-generic-lowering.h" | 8 #include "src/compiler/js-generic-lowering.h" | 
| 9 #include "src/compiler/js-graph.h" | 9 #include "src/compiler/js-graph.h" | 
| 10 #include "src/compiler/machine-operator.h" | 10 #include "src/compiler/machine-operator.h" | 
| (...skipping 98 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 109 REPLACE_COMPARE_IC_CALL_WITH_LANGUAGE_MODE(JSGreaterThan, Token::GT) | 109 REPLACE_COMPARE_IC_CALL_WITH_LANGUAGE_MODE(JSGreaterThan, Token::GT) | 
| 110 REPLACE_COMPARE_IC_CALL_WITH_LANGUAGE_MODE(JSLessThanOrEqual, Token::LTE) | 110 REPLACE_COMPARE_IC_CALL_WITH_LANGUAGE_MODE(JSLessThanOrEqual, Token::LTE) | 
| 111 REPLACE_COMPARE_IC_CALL_WITH_LANGUAGE_MODE(JSGreaterThanOrEqual, Token::GTE) | 111 REPLACE_COMPARE_IC_CALL_WITH_LANGUAGE_MODE(JSGreaterThanOrEqual, Token::GTE) | 
| 112 #undef REPLACE_COMPARE_IC_CALL_WITH_LANGUAGE_MODE | 112 #undef REPLACE_COMPARE_IC_CALL_WITH_LANGUAGE_MODE | 
| 113 | 113 | 
| 114 | 114 | 
| 115 #define REPLACE_RUNTIME_CALL(op, fun)             \ | 115 #define REPLACE_RUNTIME_CALL(op, fun)             \ | 
| 116   void JSGenericLowering::Lower##op(Node* node) { \ | 116   void JSGenericLowering::Lower##op(Node* node) { \ | 
| 117     ReplaceWithRuntimeCall(node, fun);            \ | 117     ReplaceWithRuntimeCall(node, fun);            \ | 
| 118   } | 118   } | 
| 119 REPLACE_RUNTIME_CALL(JSCreateFunctionContext, Runtime::kNewFunctionContext) |  | 
| 120 REPLACE_RUNTIME_CALL(JSCreateWithContext, Runtime::kPushWithContext) | 119 REPLACE_RUNTIME_CALL(JSCreateWithContext, Runtime::kPushWithContext) | 
| 121 REPLACE_RUNTIME_CALL(JSCreateModuleContext, Runtime::kPushModuleContext) | 120 REPLACE_RUNTIME_CALL(JSCreateModuleContext, Runtime::kPushModuleContext) | 
| 122 REPLACE_RUNTIME_CALL(JSConvertReceiver, Runtime::kConvertReceiver) | 121 REPLACE_RUNTIME_CALL(JSConvertReceiver, Runtime::kConvertReceiver) | 
| 123 #undef REPLACE_RUNTIME | 122 #undef REPLACE_RUNTIME | 
| 124 | 123 | 
| 125 | 124 | 
| 126 static CallDescriptor::Flags FlagsForNode(Node* node) { | 125 static CallDescriptor::Flags FlagsForNode(Node* node) { | 
| 127   CallDescriptor::Flags result = CallDescriptor::kNoFlags; | 126   CallDescriptor::Flags result = CallDescriptor::kNoFlags; | 
| 128   if (OperatorProperties::GetFrameStateInputCount(node->op()) > 0) { | 127   if (OperatorProperties::GetFrameStateInputCount(node->op()) > 0) { | 
| 129     result |= CallDescriptor::kNeedsFrameState; | 128     result |= CallDescriptor::kNeedsFrameState; | 
| (...skipping 338 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 468       node->InsertInput(zone(), 1, jsgraph()->Constant(p.start_index())); | 467       node->InsertInput(zone(), 1, jsgraph()->Constant(p.start_index())); | 
| 469       ReplaceWithRuntimeCall(node, Runtime::kNewRestArguments_Generic); | 468       ReplaceWithRuntimeCall(node, Runtime::kNewRestArguments_Generic); | 
| 470       break; | 469       break; | 
| 471   } | 470   } | 
| 472 } | 471 } | 
| 473 | 472 | 
| 474 | 473 | 
| 475 void JSGenericLowering::LowerJSCreateArray(Node* node) { | 474 void JSGenericLowering::LowerJSCreateArray(Node* node) { | 
| 476   CreateArrayParameters const& p = CreateArrayParametersOf(node->op()); | 475   CreateArrayParameters const& p = CreateArrayParametersOf(node->op()); | 
| 477   int const arity = static_cast<int>(p.arity()); | 476   int const arity = static_cast<int>(p.arity()); | 
| 478   Node* new_target = node->InputAt(1); | 477   Handle<AllocationSite> const site = p.site(); | 
|  | 478 | 
| 479   // TODO(turbofan): We embed the AllocationSite from the Operator at this | 479   // TODO(turbofan): We embed the AllocationSite from the Operator at this | 
| 480   // point, which we should not do once we want to both consume the feedback | 480   // point, which we should not do once we want to both consume the feedback | 
| 481   // but at the same time shared the optimized code across native contexts, | 481   // but at the same time shared the optimized code across native contexts, | 
| 482   // as the AllocationSite is associated with a single native context (it's | 482   // as the AllocationSite is associated with a single native context (it's | 
| 483   // stored in the type feedback vector after all). Once we go for cross | 483   // stored in the type feedback vector after all). Once we go for cross | 
| 484   // context code generation, we should somehow find a way to get to the | 484   // context code generation, we should somehow find a way to get to the | 
| 485   // allocation site for the actual native context at runtime. | 485   // allocation site for the actual native context at runtime. | 
| 486   Node* type_info = p.site().is_null() ? jsgraph()->UndefinedConstant() | 486   if (!site.is_null()) { | 
| 487                                        : jsgraph()->HeapConstant(p.site()); | 487     // Reduce {node} to the appropriate ArrayConstructorStub backend. | 
| 488   node->RemoveInput(1); | 488     // Note that these stubs "behave" like JSFunctions, which means they | 
| 489   node->InsertInput(zone(), 1 + arity, new_target); | 489     // expect a receiver on the stack, which they remove. We just push | 
| 490   node->InsertInput(zone(), 2 + arity, type_info); | 490     // undefined for the receiver. | 
| 491   ReplaceWithRuntimeCall(node, Runtime::kNewArray, arity + 3); | 491     ElementsKind elements_kind = site->GetElementsKind(); | 
|  | 492     AllocationSiteOverrideMode override_mode = | 
|  | 493         (AllocationSite::GetMode(elements_kind) == TRACK_ALLOCATION_SITE) | 
|  | 494             ? DISABLE_ALLOCATION_SITES | 
|  | 495             : DONT_OVERRIDE; | 
|  | 496     if (arity == 0) { | 
|  | 497       ArrayNoArgumentConstructorStub stub(isolate(), elements_kind, | 
|  | 498                                           override_mode); | 
|  | 499       CallDescriptor* desc = Linkage::GetStubCallDescriptor( | 
|  | 500           isolate(), graph()->zone(), stub.GetCallInterfaceDescriptor(), 1, | 
|  | 501           CallDescriptor::kNeedsFrameState); | 
|  | 502       node->ReplaceInput(0, jsgraph()->HeapConstant(stub.GetCode())); | 
|  | 503       node->InsertInput(graph()->zone(), 2, jsgraph()->HeapConstant(site)); | 
|  | 504       node->InsertInput(graph()->zone(), 3, jsgraph()->UndefinedConstant()); | 
|  | 505       NodeProperties::ChangeOp(node, common()->Call(desc)); | 
|  | 506     } else if (arity == 1) { | 
|  | 507       // TODO(bmeurer): Optimize for the 0 length non-holey case? | 
|  | 508       ArraySingleArgumentConstructorStub stub( | 
|  | 509           isolate(), GetHoleyElementsKind(elements_kind), override_mode); | 
|  | 510       CallDescriptor* desc = Linkage::GetStubCallDescriptor( | 
|  | 511           isolate(), graph()->zone(), stub.GetCallInterfaceDescriptor(), 2, | 
|  | 512           CallDescriptor::kNeedsFrameState); | 
|  | 513       node->ReplaceInput(0, jsgraph()->HeapConstant(stub.GetCode())); | 
|  | 514       node->InsertInput(graph()->zone(), 2, jsgraph()->HeapConstant(site)); | 
|  | 515       node->InsertInput(graph()->zone(), 3, jsgraph()->Int32Constant(1)); | 
|  | 516       node->InsertInput(graph()->zone(), 4, jsgraph()->UndefinedConstant()); | 
|  | 517       NodeProperties::ChangeOp(node, common()->Call(desc)); | 
|  | 518     } else { | 
|  | 519       ArrayNArgumentsConstructorStub stub(isolate(), elements_kind, | 
|  | 520                                           override_mode); | 
|  | 521       CallDescriptor* desc = Linkage::GetStubCallDescriptor( | 
|  | 522           isolate(), graph()->zone(), stub.GetCallInterfaceDescriptor(), | 
|  | 523           arity + 1, CallDescriptor::kNeedsFrameState); | 
|  | 524       node->ReplaceInput(0, jsgraph()->HeapConstant(stub.GetCode())); | 
|  | 525       node->InsertInput(graph()->zone(), 2, jsgraph()->HeapConstant(site)); | 
|  | 526       node->InsertInput(graph()->zone(), 3, jsgraph()->Int32Constant(arity)); | 
|  | 527       node->InsertInput(graph()->zone(), 4, jsgraph()->UndefinedConstant()); | 
|  | 528       NodeProperties::ChangeOp(node, common()->Call(desc)); | 
|  | 529     } | 
|  | 530   } else { | 
|  | 531     Node* new_target = node->InputAt(1); | 
|  | 532     Node* type_info = site.is_null() ? jsgraph()->UndefinedConstant() | 
|  | 533                                      : jsgraph()->HeapConstant(site); | 
|  | 534     node->RemoveInput(1); | 
|  | 535     node->InsertInput(zone(), 1 + arity, new_target); | 
|  | 536     node->InsertInput(zone(), 2 + arity, type_info); | 
|  | 537     ReplaceWithRuntimeCall(node, Runtime::kNewArray, arity + 3); | 
|  | 538   } | 
| 492 } | 539 } | 
| 493 | 540 | 
| 494 | 541 | 
| 495 void JSGenericLowering::LowerJSCreateClosure(Node* node) { | 542 void JSGenericLowering::LowerJSCreateClosure(Node* node) { | 
| 496   CreateClosureParameters p = CreateClosureParametersOf(node->op()); | 543   CreateClosureParameters const& p = CreateClosureParametersOf(node->op()); | 
| 497   node->InsertInput(zone(), 0, jsgraph()->HeapConstant(p.shared_info())); | 544   CallDescriptor::Flags flags = AdjustFrameStatesForCall(node); | 
| 498   ReplaceWithRuntimeCall(node, (p.pretenure() == TENURED) | 545   Handle<SharedFunctionInfo> const shared_info = p.shared_info(); | 
| 499                                    ? Runtime::kNewClosure_Tenured | 546   node->InsertInput(zone(), 0, jsgraph()->HeapConstant(shared_info)); | 
| 500                                    : Runtime::kNewClosure); | 547 | 
|  | 548   // Use the FastNewClosureStub that allocates in new space only for nested | 
|  | 549   // functions that don't need literals cloning. | 
|  | 550   if (p.pretenure() == NOT_TENURED && shared_info->num_literals() == 0) { | 
|  | 551     Callable callable = CodeFactory::FastNewClosure( | 
|  | 552         isolate(), shared_info->language_mode(), shared_info->kind()); | 
|  | 553     ReplaceWithStubCall(node, callable, flags); | 
|  | 554   } else { | 
|  | 555     ReplaceWithRuntimeCall(node, (p.pretenure() == TENURED) | 
|  | 556                                      ? Runtime::kNewClosure_Tenured | 
|  | 557                                      : Runtime::kNewClosure); | 
|  | 558   } | 
| 501 } | 559 } | 
| 502 | 560 | 
| 503 | 561 | 
|  | 562 void JSGenericLowering::LowerJSCreateFunctionContext(Node* node) { | 
|  | 563   int const slot_count = OpParameter<int>(node->op()); | 
|  | 564   CallDescriptor::Flags flags = AdjustFrameStatesForCall(node); | 
|  | 565 | 
|  | 566   // Use the FastNewContextStub only for function contexts up maximum size. | 
|  | 567   if (slot_count <= FastNewContextStub::kMaximumSlots) { | 
|  | 568     Callable callable = CodeFactory::FastNewContext(isolate(), slot_count); | 
|  | 569     ReplaceWithStubCall(node, callable, flags); | 
|  | 570   } else { | 
|  | 571     ReplaceWithRuntimeCall(node, Runtime::kNewFunctionContext); | 
|  | 572   } | 
|  | 573 } | 
|  | 574 | 
|  | 575 | 
| 504 void JSGenericLowering::LowerJSCreateIterResultObject(Node* node) { | 576 void JSGenericLowering::LowerJSCreateIterResultObject(Node* node) { | 
| 505   ReplaceWithRuntimeCall(node, Runtime::kCreateIterResultObject); | 577   ReplaceWithRuntimeCall(node, Runtime::kCreateIterResultObject); | 
| 506 } | 578 } | 
| 507 | 579 | 
| 508 | 580 | 
| 509 void JSGenericLowering::LowerJSCreateLiteralArray(Node* node) { | 581 void JSGenericLowering::LowerJSCreateLiteralArray(Node* node) { | 
| 510   CreateLiteralParameters const& p = CreateLiteralParametersOf(node->op()); | 582   CreateLiteralParameters const& p = CreateLiteralParametersOf(node->op()); | 
|  | 583   CallDescriptor::Flags flags = AdjustFrameStatesForCall(node); | 
|  | 584   int const length = Handle<FixedArray>::cast(p.constant())->length(); | 
| 511   node->InsertInput(zone(), 1, jsgraph()->SmiConstant(p.index())); | 585   node->InsertInput(zone(), 1, jsgraph()->SmiConstant(p.index())); | 
| 512   node->InsertInput(zone(), 2, jsgraph()->HeapConstant(p.constant())); | 586   node->InsertInput(zone(), 2, jsgraph()->HeapConstant(p.constant())); | 
| 513   node->InsertInput(zone(), 3, jsgraph()->SmiConstant(p.flags())); | 587 | 
| 514   ReplaceWithRuntimeCall(node, Runtime::kCreateArrayLiteral); | 588   // Use the FastCloneShallowArrayStub only for shallow boilerplates up to the | 
|  | 589   // initial length limit for arrays with "fast" elements kind. | 
|  | 590   if ((p.flags() & ArrayLiteral::kShallowElements) != 0 && | 
|  | 591       (p.flags() & ArrayLiteral::kIsStrong) == 0 && | 
|  | 592       length < JSArray::kInitialMaxFastElementArray) { | 
|  | 593     Callable callable = CodeFactory::FastCloneShallowArray(isolate()); | 
|  | 594     ReplaceWithStubCall(node, callable, flags); | 
|  | 595   } else { | 
|  | 596     node->InsertInput(zone(), 3, jsgraph()->SmiConstant(p.flags())); | 
|  | 597     ReplaceWithRuntimeCall(node, Runtime::kCreateArrayLiteral); | 
|  | 598   } | 
| 515 } | 599 } | 
| 516 | 600 | 
| 517 | 601 | 
| 518 void JSGenericLowering::LowerJSCreateLiteralObject(Node* node) { | 602 void JSGenericLowering::LowerJSCreateLiteralObject(Node* node) { | 
| 519   CreateLiteralParameters const& p = CreateLiteralParametersOf(node->op()); | 603   CreateLiteralParameters const& p = CreateLiteralParametersOf(node->op()); | 
|  | 604   CallDescriptor::Flags flags = AdjustFrameStatesForCall(node); | 
|  | 605   int const length = Handle<FixedArray>::cast(p.constant())->length(); | 
| 520   node->InsertInput(zone(), 1, jsgraph()->SmiConstant(p.index())); | 606   node->InsertInput(zone(), 1, jsgraph()->SmiConstant(p.index())); | 
| 521   node->InsertInput(zone(), 2, jsgraph()->HeapConstant(p.constant())); | 607   node->InsertInput(zone(), 2, jsgraph()->HeapConstant(p.constant())); | 
| 522   node->InsertInput(zone(), 3, jsgraph()->SmiConstant(p.flags())); | 608   node->InsertInput(zone(), 3, jsgraph()->SmiConstant(p.flags())); | 
| 523   ReplaceWithRuntimeCall(node, Runtime::kCreateObjectLiteral); | 609 | 
|  | 610   // Use the FastCloneShallowObjectStub only for shallow boilerplates without | 
|  | 611   // elements up to the number of properties that the stubs can handle. | 
|  | 612   if ((p.flags() & ObjectLiteral::kShallowProperties) != 0 && | 
|  | 613       length <= FastCloneShallowObjectStub::kMaximumClonedProperties) { | 
|  | 614     Callable callable = CodeFactory::FastCloneShallowObject(isolate(), length); | 
|  | 615     ReplaceWithStubCall(node, callable, flags); | 
|  | 616   } else { | 
|  | 617     ReplaceWithRuntimeCall(node, Runtime::kCreateObjectLiteral); | 
|  | 618   } | 
| 524 } | 619 } | 
| 525 | 620 | 
| 526 | 621 | 
| 527 void JSGenericLowering::LowerJSCreateLiteralRegExp(Node* node) { | 622 void JSGenericLowering::LowerJSCreateLiteralRegExp(Node* node) { | 
| 528   CreateLiteralParameters const& p = CreateLiteralParametersOf(node->op()); | 623   CreateLiteralParameters const& p = CreateLiteralParametersOf(node->op()); | 
| 529   CallDescriptor::Flags flags = AdjustFrameStatesForCall(node); | 624   CallDescriptor::Flags flags = AdjustFrameStatesForCall(node); | 
| 530   Callable callable = CodeFactory::FastCloneRegExp(isolate()); | 625   Callable callable = CodeFactory::FastCloneRegExp(isolate()); | 
| 531   Node* literal_index = jsgraph()->SmiConstant(p.index()); | 626   Node* literal_index = jsgraph()->SmiConstant(p.index()); | 
| 532   Node* literal_flags = jsgraph()->SmiConstant(p.flags()); | 627   Node* literal_flags = jsgraph()->SmiConstant(p.flags()); | 
| 533   Node* pattern = jsgraph()->HeapConstant(p.constant()); | 628   Node* pattern = jsgraph()->HeapConstant(p.constant()); | 
| (...skipping 173 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 707 } | 802 } | 
| 708 | 803 | 
| 709 | 804 | 
| 710 MachineOperatorBuilder* JSGenericLowering::machine() const { | 805 MachineOperatorBuilder* JSGenericLowering::machine() const { | 
| 711   return jsgraph()->machine(); | 806   return jsgraph()->machine(); | 
| 712 } | 807 } | 
| 713 | 808 | 
| 714 }  // namespace compiler | 809 }  // namespace compiler | 
| 715 }  // namespace internal | 810 }  // namespace internal | 
| 716 }  // namespace v8 | 811 }  // namespace v8 | 
| OLD | NEW | 
|---|