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->function() != NULL) {
43 // If we already have the function literal, use the number of parameters
45 return GetJSCallDescriptor(zone, info->is_osr(),
46 1 + info->function()->parameter_count(),
47 CallDescriptor::kNoFlags);
49 if (!info->closure().is_null()) {
50 // If we are compiling a JS function, use a JS call descriptor,
52 SharedFunctionInfo* shared = info->closure()->shared();
53 return GetJSCallDescriptor(zone, info->is_osr(),
54 1 + shared->internal_formal_parameter_count(),
55 CallDescriptor::kNoFlags);
57 if (info->code_stub() != NULL) {
58 // Use the code stub interface descriptor.
59 CallInterfaceDescriptor descriptor =
60 info->code_stub()->GetCallInterfaceDescriptor();
61 return GetStubCallDescriptor(info->isolate(), zone, descriptor, 0,
62 CallDescriptor::kNoFlags,
63 Operator::kNoProperties);
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::kPushBlockContext:
118 case Runtime::kPushCatchContext:
119 case Runtime::kReThrow:
120 case Runtime::kSetProperty: // TODO(jarin): Is it safe?
121 case Runtime::kStringCompare:
122 case Runtime::kStringEquals:
123 case Runtime::kToFastProperties: // TODO(jarin): Is it safe?
124 case Runtime::kTraceEnter:
125 case Runtime::kTraceExit:
126 case Runtime::kTypeof:
127 case Runtime::kNewRestParamSlow:
129 case Runtime::kInlineArguments:
130 case Runtime::kInlineCallFunction:
131 case Runtime::kInlineDateField:
132 case Runtime::kInlineOptimizedGetPrototype:
133 case Runtime::kInlineRegExpExec:
139 // Most inlined runtime functions (except the ones listed above) can be called
140 // without a FrameState or will be lowered by JSIntrinsicLowering internally.
141 const Runtime::Function* const f = Runtime::FunctionForId(function);
142 if (f->intrinsic_type == Runtime::IntrinsicType::INLINE) return false;
148 //==============================================================================
149 // Provide unimplemented methods on unsupported architectures, to at least link.
150 //==============================================================================
151 #if !V8_TURBOFAN_BACKEND
152 CallDescriptor* Linkage::GetJSCallDescriptor(Zone* zone, bool is_osr,
154 CallDescriptor::Flags flags) {
160 LinkageLocation Linkage::GetOsrValueLocation(int index) const {
162 return LinkageLocation(-1); // Dummy value
166 CallDescriptor* Linkage::GetRuntimeCallDescriptor(
167 Zone* zone, Runtime::FunctionId function, int parameter_count,
168 Operator::Properties properties) {
174 CallDescriptor* Linkage::GetStubCallDescriptor(
175 Isolate* isolate, Zone* zone, const CallInterfaceDescriptor& descriptor,
176 int stack_parameter_count, CallDescriptor::Flags flags,
177 Operator::Properties properties) {
183 CallDescriptor* Linkage::GetSimplifiedCDescriptor(Zone* zone,
184 const MachineSignature* sig) {
188 #endif // !V8_TURBOFAN_BACKEND
191 } // namespace v8::internal::compiler