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
3 // found in the LICENSE file.
5 #include "src/code-stubs.h"
6 #include "src/compiler.h"
7 #include "src/compiler/linkage.h"
8 #include "src/compiler/node.h"
9 #include "src/compiler/pipeline.h"
10 #include "src/scopes.h"
17 std::ostream& operator<<(std::ostream& os, const CallDescriptor::Kind& k) {
19 case CallDescriptor::kCallCodeObject:
22 case CallDescriptor::kCallJSFunction:
25 case CallDescriptor::kCallAddress:
33 std::ostream& operator<<(std::ostream& os, const CallDescriptor& d) {
34 // TODO(svenpanne) Output properties etc. and be less cryptic.
35 return os << d.kind() << ":" << d.debug_name() << ":r" << d.ReturnCount()
36 << "j" << d.JSParameterCount() << "i" << d.InputCount() << "f"
37 << d.FrameStateCount();
41 CallDescriptor* Linkage::ComputeIncoming(Zone* zone, CompilationInfo* info) {
42 if (info->code_stub() != NULL) {
43 // Use the code stub interface descriptor.
44 CallInterfaceDescriptor descriptor =
45 info->code_stub()->GetCallInterfaceDescriptor();
46 return GetStubCallDescriptor(info->isolate(), zone, descriptor, 0,
47 CallDescriptor::kNoFlags,
48 Operator::kNoProperties);
50 if (info->function() != NULL) {
51 // If we already have the function literal, use the number of parameters
53 return GetJSCallDescriptor(zone, info->is_osr(),
54 1 + info->function()->parameter_count(),
55 CallDescriptor::kNoFlags);
57 if (!info->closure().is_null()) {
58 // If we are compiling a JS function, use a JS call descriptor,
60 SharedFunctionInfo* shared = info->closure()->shared();
61 return GetJSCallDescriptor(zone, info->is_osr(),
62 1 + shared->internal_formal_parameter_count(),
63 CallDescriptor::kNoFlags);
65 return NULL; // TODO(titzer): ?
69 FrameOffset Linkage::GetFrameOffset(int spill_slot, Frame* frame,
71 if (frame->GetSpillSlotCount() > 0 || incoming_->IsJSFunctionCall() ||
72 incoming_->kind() == CallDescriptor::kCallAddress) {
74 int register_save_area_size = frame->GetRegisterSaveAreaSize();
75 if (spill_slot >= 0) {
76 // Local or spill slot. Skip the frame pointer, function, and
77 // context in the fixed part of the frame.
79 -(spill_slot + 1) * kPointerSize - register_save_area_size + extra;
81 // Incoming parameter. Skip the return address.
82 offset = -(spill_slot + 1) * kPointerSize + kFPOnStackSize +
83 kPCOnStackSize + extra;
85 return FrameOffset::FromFramePointer(offset);
87 // No frame. Retrieve all parameters relative to stack pointer.
88 DCHECK(spill_slot < 0); // Must be a parameter.
89 int register_save_area_size = frame->GetRegisterSaveAreaSize();
90 int offset = register_save_area_size - (spill_slot + 1) * kPointerSize +
91 kPCOnStackSize + extra;
92 return FrameOffset::FromStackPointer(offset);
98 bool Linkage::NeedsFrameState(Runtime::FunctionId function) {
99 if (!FLAG_turbo_deoptimization) {
103 // Most runtime functions need a FrameState. A few chosen ones that we know
104 // not to call into arbitrary JavaScript, not to throw, and not to deoptimize
105 // are blacklisted here and can be called without a FrameState.
107 case Runtime::kDeclareGlobals: // TODO(jarin): Is it safe?
108 case Runtime::kDefineClassMethod: // TODO(jarin): Is it safe?
109 case Runtime::kDefineGetterPropertyUnchecked: // TODO(jarin): Is it safe?
110 case Runtime::kDefineSetterPropertyUnchecked: // TODO(jarin): Is it safe?
111 case Runtime::kForInCacheArrayLength:
112 case Runtime::kForInInit:
113 case Runtime::kForInNext:
114 case Runtime::kNewArguments:
115 case Runtime::kNewClosure:
116 case Runtime::kNewFunctionContext:
117 case Runtime::kNewRestParamSlow:
118 case Runtime::kPushBlockContext:
119 case Runtime::kPushCatchContext:
120 case Runtime::kReThrow:
121 case Runtime::kSetProperty: // TODO(jarin): Is it safe?
122 case Runtime::kStringCompareRT:
123 case Runtime::kStringEquals:
124 case Runtime::kToFastProperties: // TODO(jarin): Is it safe?
125 case Runtime::kTraceEnter:
126 case Runtime::kTraceExit:
127 case Runtime::kTypeof:
129 case Runtime::kInlineArguments:
130 case Runtime::kInlineCallFunction:
131 case Runtime::kInlineDateField:
132 case Runtime::kInlineDeoptimizeNow:
133 case Runtime::kInlineGetPrototype:
134 case Runtime::kInlineRegExpExec:
140 // Most inlined runtime functions (except the ones listed above) can be called
141 // without a FrameState or will be lowered by JSIntrinsicLowering internally.
142 const Runtime::Function* const f = Runtime::FunctionForId(function);
143 if (f->intrinsic_type == Runtime::IntrinsicType::INLINE) return false;
149 //==============================================================================
150 // Provide unimplemented methods on unsupported architectures, to at least link.
151 //==============================================================================
152 #if !V8_TURBOFAN_BACKEND
153 CallDescriptor* Linkage::GetJSCallDescriptor(Zone* zone, bool is_osr,
155 CallDescriptor::Flags flags) {
161 LinkageLocation Linkage::GetOsrValueLocation(int index) const {
163 return LinkageLocation(-1); // Dummy value
167 CallDescriptor* Linkage::GetRuntimeCallDescriptor(
168 Zone* zone, Runtime::FunctionId function, int parameter_count,
169 Operator::Properties properties) {
175 CallDescriptor* Linkage::GetStubCallDescriptor(
176 Isolate* isolate, Zone* zone, const CallInterfaceDescriptor& descriptor,
177 int stack_parameter_count, CallDescriptor::Flags flags,
178 Operator::Properties properties, MachineType return_type) {
184 CallDescriptor* Linkage::GetSimplifiedCDescriptor(Zone* zone,
185 const MachineSignature* sig) {
189 #endif // !V8_TURBOFAN_BACKEND
192 } // namespace v8::internal::compiler