Index: src/compiler/linkage.h |
diff --git a/src/compiler/linkage.h b/src/compiler/linkage.h |
new file mode 100644 |
index 0000000000000000000000000000000000000000..9d9c50876aa1204ca1aff307d3b68540da0faf62 |
--- /dev/null |
+++ b/src/compiler/linkage.h |
@@ -0,0 +1,188 @@ |
+// Copyright 2014 the V8 project authors. All rights reserved. |
+// Use of this source code is governed by a BSD-style license that can be |
+// found in the LICENSE file. |
+ |
+#ifndef V8_COMPILER_LINKAGE_H_ |
+#define V8_COMPILER_LINKAGE_H_ |
+ |
+#include "src/v8.h" |
+ |
+#include "src/code-stubs.h" |
+#include "src/compiler/frame.h" |
+#include "src/compiler/machine-operator.h" |
+#include "src/compiler/node.h" |
+#include "src/compiler/operator.h" |
+#include "src/zone.h" |
+ |
+namespace v8 { |
+namespace internal { |
+namespace compiler { |
+ |
+// Describes the location for a parameter or a return value to a call. |
+// TODO(titzer): replace with Radium locations when they are ready. |
+class LinkageLocation { |
+ public: |
+ LinkageLocation(MachineRepresentation rep, int location) |
+ : rep_(rep), location_(location) {} |
+ |
+ inline MachineRepresentation representation() const { return rep_; } |
+ |
+ static const int16_t ANY_REGISTER = 32767; |
+ |
+ private: |
+ friend class CallDescriptor; |
+ friend class OperandGenerator; |
+ MachineRepresentation rep_; |
+ int16_t location_; // >= 0 implies register, otherwise stack slot. |
+}; |
+ |
+ |
+class CallDescriptor : public ZoneObject { |
+ public: |
+ // Describes whether the first parameter is a code object, a JSFunction, |
+ // or an address--all of which require different machine sequences to call. |
+ enum Kind { kCallCodeObject, kCallJSFunction, kCallAddress }; |
+ |
+ enum DeoptimizationSupport { kCanDeoptimize, kCannotDeoptimize }; |
+ |
+ CallDescriptor(Kind kind, int8_t return_count, int16_t parameter_count, |
+ int16_t input_count, LinkageLocation* locations, |
+ Operator::Property properties, RegList callee_saved_registers, |
+ DeoptimizationSupport deoptimization_support, |
+ const char* debug_name = "") |
+ : kind_(kind), |
+ return_count_(return_count), |
+ parameter_count_(parameter_count), |
+ input_count_(input_count), |
+ locations_(locations), |
+ properties_(properties), |
+ callee_saved_registers_(callee_saved_registers), |
+ deoptimization_support_(deoptimization_support), |
+ debug_name_(debug_name) {} |
+ // Returns the kind of this call. |
+ Kind kind() const { return kind_; } |
+ |
+ // Returns {true} if this descriptor is a call to a JSFunction. |
+ bool IsJSFunctionCall() const { return kind_ == kCallJSFunction; } |
+ |
+ // The number of return values from this call, usually 0 or 1. |
+ int ReturnCount() const { return return_count_; } |
+ |
+ // The number of JavaScript parameters to this call, including receiver, |
+ // but not the context. |
+ int ParameterCount() const { return parameter_count_; } |
+ |
+ int InputCount() const { return input_count_; } |
+ |
+ bool CanLazilyDeoptimize() const { |
+ return deoptimization_support_ == kCanDeoptimize; |
+ } |
+ |
+ LinkageLocation GetReturnLocation(int index) { |
+ ASSERT(index < return_count_); |
+ return locations_[0 + index]; // return locations start at 0. |
+ } |
+ |
+ LinkageLocation GetInputLocation(int index) { |
+ ASSERT(index < input_count_ + 1); // input_count + 1 is the context. |
+ return locations_[return_count_ + index]; // inputs start after returns. |
+ } |
+ |
+ // Operator properties describe how this call can be optimized, if at all. |
+ Operator::Property properties() const { return properties_; } |
+ |
+ // Get the callee-saved registers, if any, across this call. |
+ RegList CalleeSavedRegisters() { return callee_saved_registers_; } |
+ |
+ const char* debug_name() const { return debug_name_; } |
+ |
+ private: |
+ friend class Linkage; |
+ |
+ Kind kind_; |
+ int8_t return_count_; |
+ int16_t parameter_count_; |
+ int16_t input_count_; |
+ LinkageLocation* locations_; |
+ Operator::Property properties_; |
+ RegList callee_saved_registers_; |
+ DeoptimizationSupport deoptimization_support_; |
+ const char* debug_name_; |
+}; |
+ |
+OStream& operator<<(OStream& os, const CallDescriptor& d); |
+OStream& operator<<(OStream& os, const CallDescriptor::Kind& k); |
+ |
+// Defines the linkage for a compilation, including the calling conventions |
+// for incoming parameters and return value(s) as well as the outgoing calling |
+// convention for any kind of call. Linkage is generally architecture-specific. |
+// |
+// Can be used to translate {arg_index} (i.e. index of the call node input) as |
+// well as {param_index} (i.e. as stored in parameter nodes) into an operator |
+// representing the architecture-specific location. The following call node |
+// layouts are supported (where {n} is the number value inputs): |
+// |
+// #0 #1 #2 #3 [...] #n |
+// Call[CodeStub] code, arg 1, arg 2, arg 3, [...], context |
+// Call[JSFunction] function, rcvr, arg 1, arg 2, [...], context |
+// Call[Runtime] CEntryStub, arg 1, arg 2, arg 3, [...], fun, #arg, context |
+class Linkage : public ZoneObject { |
+ public: |
+ explicit Linkage(CompilationInfo* info); |
+ explicit Linkage(CompilationInfo* info, CallDescriptor* incoming) |
+ : info_(info), incoming_(incoming) {} |
+ |
+ // The call descriptor for this compilation unit describes the locations |
+ // of incoming parameters and the outgoing return value(s). |
+ CallDescriptor* GetIncomingDescriptor() { return incoming_; } |
+ CallDescriptor* GetJSCallDescriptor(int parameter_count); |
+ static CallDescriptor* GetJSCallDescriptor(int parameter_count, Zone* zone); |
+ CallDescriptor* GetRuntimeCallDescriptor( |
+ Runtime::FunctionId function, int parameter_count, |
+ Operator::Property properties, |
+ CallDescriptor::DeoptimizationSupport can_deoptimize = |
+ CallDescriptor::kCannotDeoptimize); |
+ static CallDescriptor* GetRuntimeCallDescriptor( |
+ Runtime::FunctionId function, int parameter_count, |
+ Operator::Property properties, |
+ CallDescriptor::DeoptimizationSupport can_deoptimize, Zone* zone); |
+ |
+ CallDescriptor* GetStubCallDescriptor(CodeStubInterfaceDescriptor* descriptor, |
+ int stack_parameter_count = 0); |
+ |
+ // Creates a call descriptor for simplified C calls that is appropriate |
+ // for the host platform. This simplified calling convention only supports |
+ // integers and pointers of one word size each, i.e. no floating point, |
+ // structs, pointers to members, etc. |
+ static CallDescriptor* GetSimplifiedCDescriptor( |
+ Zone* zone, int num_params, MachineRepresentation return_type, |
+ const MachineRepresentation* param_types); |
+ |
+ // Get the location of an (incoming) parameter to this function. |
+ LinkageLocation GetParameterLocation(int index) { |
+ return incoming_->GetInputLocation(index + 1); |
+ } |
+ |
+ // Get the location where this function should place its return value. |
+ LinkageLocation GetReturnLocation() { |
+ return incoming_->GetReturnLocation(0); |
+ } |
+ |
+ // Get the frame offset for a given spill slot. The location depends on the |
+ // calling convention and the specific frame layout, and may thus be |
+ // architecture-specific. Negative spill slots indicate arguments on the |
+ // caller's frame. The {extra} parameter indicates an additional offset from |
+ // the frame offset, e.g. to index into part of a double slot. |
+ FrameOffset GetFrameOffset(int spill_slot, Frame* frame, int extra = 0); |
+ |
+ CompilationInfo* info() const { return info_; } |
+ |
+ private: |
+ CompilationInfo* info_; |
+ CallDescriptor* incoming_; |
+}; |
+} |
+} |
+} // namespace v8::internal::compiler |
+ |
+#endif // V8_COMPILER_LINKAGE_H_ |