Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(250)

Unified Diff: src/compiler/code-assembler.h

Issue 1875583003: Separate CodeAssembler and CodeStubAssembler (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Fix gn build. Again. Created 4 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « src/code-stubs.cc ('k') | src/compiler/code-assembler.cc » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: src/compiler/code-assembler.h
diff --git a/src/compiler/code-assembler.h b/src/compiler/code-assembler.h
new file mode 100644
index 0000000000000000000000000000000000000000..f70620ef1bf820ac5ca254bf9c18b7cc961375f8
--- /dev/null
+++ b/src/compiler/code-assembler.h
@@ -0,0 +1,406 @@
+// Copyright 2015 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_CODE_ASSEMBLER_H_
+#define V8_COMPILER_CODE_ASSEMBLER_H_
+
+#include <map>
+
+// Clients of this interface shouldn't depend on lots of compiler internals.
+// Do not include anything from src/compiler here!
+#include "src/allocation.h"
+#include "src/builtins.h"
+#include "src/heap/heap.h"
+#include "src/machine-type.h"
+#include "src/runtime/runtime.h"
+#include "src/zone-containers.h"
+
+namespace v8 {
+namespace internal {
+
+class Callable;
+class CallInterfaceDescriptor;
+class Isolate;
+class Factory;
+class Zone;
+
+namespace compiler {
+
+class CallDescriptor;
+class Graph;
+class Node;
+class Operator;
+class RawMachineAssembler;
+class RawMachineLabel;
+class Schedule;
+
+#define CODE_ASSEMBLER_COMPARE_BINARY_OP_LIST(V) \
+ V(Float32Equal) \
+ V(Float32LessThan) \
+ V(Float32LessThanOrEqual) \
+ V(Float32GreaterThan) \
+ V(Float32GreaterThanOrEqual) \
+ V(Float64Equal) \
+ V(Float64LessThan) \
+ V(Float64LessThanOrEqual) \
+ V(Float64GreaterThan) \
+ V(Float64GreaterThanOrEqual) \
+ V(Int32GreaterThan) \
+ V(Int32GreaterThanOrEqual) \
+ V(Int32LessThan) \
+ V(Int32LessThanOrEqual) \
+ V(IntPtrLessThan) \
+ V(IntPtrLessThanOrEqual) \
+ V(Uint32LessThan) \
+ V(UintPtrGreaterThanOrEqual) \
+ V(WordEqual) \
+ V(WordNotEqual) \
+ V(Word32Equal) \
+ V(Word32NotEqual) \
+ V(Word64Equal) \
+ V(Word64NotEqual)
+
+#define CODE_ASSEMBLER_BINARY_OP_LIST(V) \
+ CODE_ASSEMBLER_COMPARE_BINARY_OP_LIST(V) \
+ V(Float64Add) \
+ V(Float64Sub) \
+ V(Float64Mul) \
+ V(Float64Div) \
+ V(Float64Mod) \
+ V(Float64InsertLowWord32) \
+ V(Float64InsertHighWord32) \
+ V(IntPtrAdd) \
+ V(IntPtrAddWithOverflow) \
+ V(IntPtrSub) \
+ V(IntPtrSubWithOverflow) \
+ V(IntPtrMul) \
+ V(Int32Add) \
+ V(Int32AddWithOverflow) \
+ V(Int32Sub) \
+ V(Int32Mul) \
+ V(Int32Div) \
+ V(WordOr) \
+ V(WordAnd) \
+ V(WordXor) \
+ V(WordShl) \
+ V(WordShr) \
+ V(WordSar) \
+ V(WordRor) \
+ V(Word32Or) \
+ V(Word32And) \
+ V(Word32Xor) \
+ V(Word32Shl) \
+ V(Word32Shr) \
+ V(Word32Sar) \
+ V(Word32Ror) \
+ V(Word64Or) \
+ V(Word64And) \
+ V(Word64Xor) \
+ V(Word64Shr) \
+ V(Word64Sar) \
+ V(Word64Ror)
+
+#define CODE_ASSEMBLER_UNARY_OP_LIST(V) \
+ V(Float64Neg) \
+ V(Float64Sqrt) \
+ V(Float64ExtractLowWord32) \
+ V(Float64ExtractHighWord32) \
+ V(TruncateInt64ToInt32) \
+ V(ChangeFloat64ToUint32) \
+ V(ChangeInt32ToFloat64) \
+ V(ChangeInt32ToInt64) \
+ V(ChangeUint32ToFloat64) \
+ V(ChangeUint32ToUint64) \
+ V(Float64RoundDown) \
+ V(Float64RoundUp) \
+ V(Float64RoundTruncate) \
+ V(Word32Clz)
+
+// A "public" interface used by components outside of compiler directory to
+// create code objects with TurboFan's backend. This class is mostly a thin shim
+// around the RawMachineAssembler, and its primary job is to ensure that the
+// innards of the RawMachineAssembler and other compiler implementation details
+// don't leak outside of the the compiler directory..
+//
+// V8 components that need to generate low-level code using this interface
+// should include this header--and this header only--from the compiler directory
+// (this is actually enforced). Since all interesting data structures are
+// forward declared, it's not possible for clients to peek inside the compiler
+// internals.
+//
+// In addition to providing isolation between TurboFan and code generation
+// clients, CodeAssembler also provides an abstraction for creating variables
+// and enhanced Label functionality to merge variable values along paths where
+// they have differing values, including loops.
+class CodeAssembler {
+ public:
+ // Create with CallStub linkage.
+ // |result_size| specifies the number of results returned by the stub.
+ // TODO(rmcilroy): move result_size to the CallInterfaceDescriptor.
+ CodeAssembler(Isolate* isolate, Zone* zone,
+ const CallInterfaceDescriptor& descriptor, Code::Flags flags,
+ const char* name, size_t result_size = 1);
+
+ // Create with JSCall linkage.
+ CodeAssembler(Isolate* isolate, Zone* zone, int parameter_count,
+ Code::Flags flags, const char* name);
+
+ virtual ~CodeAssembler();
+
+ Handle<Code> GenerateCode();
+
+ bool Is64() const;
+ bool IsFloat64RoundUpSupported() const;
+ bool IsFloat64RoundDownSupported() const;
+ bool IsFloat64RoundTruncateSupported() const;
+
+ class Label;
+ class Variable {
+ public:
+ explicit Variable(CodeAssembler* assembler, MachineRepresentation rep);
+ void Bind(Node* value);
+ Node* value() const;
+ MachineRepresentation rep() const;
+ bool IsBound() const;
+
+ private:
+ friend class CodeAssembler;
+ class Impl;
+ Impl* impl_;
+ };
+
+ enum AllocationFlag : uint8_t {
+ kNone = 0,
+ kDoubleAlignment = 1,
+ kPretenured = 1 << 1
+ };
+
+ typedef base::Flags<AllocationFlag> AllocationFlags;
+
+ // ===========================================================================
+ // Base Assembler
+ // ===========================================================================
+
+ // Constants.
+ Node* Int32Constant(int value);
+ Node* IntPtrConstant(intptr_t value);
+ Node* NumberConstant(double value);
+ Node* SmiConstant(Smi* value);
+ Node* HeapConstant(Handle<HeapObject> object);
+ Node* BooleanConstant(bool value);
+ Node* ExternalConstant(ExternalReference address);
+ Node* Float64Constant(double value);
+ Node* BooleanMapConstant();
+ Node* EmptyStringConstant();
+ Node* HeapNumberMapConstant();
+ Node* NaNConstant();
+ Node* NoContextConstant();
+ Node* NullConstant();
+ Node* UndefinedConstant();
+
+ Node* Parameter(int value);
+ void Return(Node* value);
+
+ void Bind(Label* label);
+ void Goto(Label* label);
+ void GotoIf(Node* condition, Label* true_label);
+ void GotoUnless(Node* condition, Label* false_label);
+ void Branch(Node* condition, Label* true_label, Label* false_label);
+
+ void Switch(Node* index, Label* default_label, int32_t* case_values,
+ Label** case_labels, size_t case_count);
+
+ // Access to the frame pointer
+ Node* LoadFramePointer();
+ Node* LoadParentFramePointer();
+
+ // Access to the stack pointer
+ Node* LoadStackPointer();
+
+ // Load raw memory location.
+ Node* Load(MachineType rep, Node* base);
+ Node* Load(MachineType rep, Node* base, Node* index);
+
+ // Store value to raw memory location.
+ Node* Store(MachineRepresentation rep, Node* base, Node* value);
+ Node* Store(MachineRepresentation rep, Node* base, Node* index, Node* value);
+ Node* StoreNoWriteBarrier(MachineRepresentation rep, Node* base, Node* value);
+ Node* StoreNoWriteBarrier(MachineRepresentation rep, Node* base, Node* index,
+ Node* value);
+
+// Basic arithmetic operations.
+#define DECLARE_CODE_ASSEMBLER_BINARY_OP(name) Node* name(Node* a, Node* b);
+ CODE_ASSEMBLER_BINARY_OP_LIST(DECLARE_CODE_ASSEMBLER_BINARY_OP)
+#undef DECLARE_CODE_ASSEMBLER_BINARY_OP
+
+ Node* WordShl(Node* value, int shift);
+
+// Unary
+#define DECLARE_CODE_ASSEMBLER_UNARY_OP(name) Node* name(Node* a);
+ CODE_ASSEMBLER_UNARY_OP_LIST(DECLARE_CODE_ASSEMBLER_UNARY_OP)
+#undef DECLARE_CODE_ASSEMBLER_UNARY_OP
+
+ Node* TruncateFloat64ToInt32RoundToZero(Node* a);
+ Node* TruncateFloat64ToInt32JavaScript(Node* a);
+
+ // Projections
+ Node* Projection(int index, Node* value);
+
+ // Calls
+ Node* CallRuntime(Runtime::FunctionId function_id, Node* context);
+ Node* CallRuntime(Runtime::FunctionId function_id, Node* context, Node* arg1);
+ Node* CallRuntime(Runtime::FunctionId function_id, Node* context, Node* arg1,
+ Node* arg2);
+ Node* CallRuntime(Runtime::FunctionId function_id, Node* context, Node* arg1,
+ Node* arg2, Node* arg3);
+ Node* CallRuntime(Runtime::FunctionId function_id, Node* context, Node* arg1,
+ Node* arg2, Node* arg3, Node* arg4);
+ Node* CallRuntime(Runtime::FunctionId function_id, Node* context, Node* arg1,
+ Node* arg2, Node* arg3, Node* arg4, Node* arg5);
+
+ Node* TailCallRuntime(Runtime::FunctionId function_id, Node* context);
+ Node* TailCallRuntime(Runtime::FunctionId function_id, Node* context,
+ Node* arg1);
+ Node* TailCallRuntime(Runtime::FunctionId function_id, Node* context,
+ Node* arg1, Node* arg2);
+ Node* TailCallRuntime(Runtime::FunctionId function_id, Node* context,
+ Node* arg1, Node* arg2, Node* arg3);
+ Node* TailCallRuntime(Runtime::FunctionId function_id, Node* context,
+ Node* arg1, Node* arg2, Node* arg3, Node* arg4);
+
+ Node* CallStub(Callable const& callable, Node* context, Node* arg1,
+ size_t result_size = 1);
+ Node* CallStub(Callable const& callable, Node* context, Node* arg1,
+ Node* arg2, size_t result_size = 1);
+ Node* CallStub(Callable const& callable, Node* context, Node* arg1,
+ Node* arg2, Node* arg3, size_t result_size = 1);
+
+ Node* CallStub(const CallInterfaceDescriptor& descriptor, Node* target,
+ Node* context, Node* arg1, size_t result_size = 1);
+ Node* CallStub(const CallInterfaceDescriptor& descriptor, Node* target,
+ Node* context, Node* arg1, Node* arg2, size_t result_size = 1);
+ Node* CallStub(const CallInterfaceDescriptor& descriptor, Node* target,
+ Node* context, Node* arg1, Node* arg2, Node* arg3,
+ size_t result_size = 1);
+ Node* CallStub(const CallInterfaceDescriptor& descriptor, Node* target,
+ Node* context, Node* arg1, Node* arg2, Node* arg3, Node* arg4,
+ size_t result_size = 1);
+ Node* CallStub(const CallInterfaceDescriptor& descriptor, Node* target,
+ Node* context, Node* arg1, Node* arg2, Node* arg3, Node* arg4,
+ Node* arg5, size_t result_size = 1);
+
+ Node* TailCallStub(Callable const& callable, Node* context, Node* arg1,
+ Node* arg2, size_t result_size = 1);
+ Node* TailCallStub(const CallInterfaceDescriptor& descriptor, Node* target,
+ Node* context, Node* arg1, Node* arg2,
+ size_t result_size = 1);
+
+ Node* TailCallBytecodeDispatch(const CallInterfaceDescriptor& descriptor,
+ Node* code_target_address, Node** args);
+
+ // ===========================================================================
+ // Macros
+ // ===========================================================================
+
+ // Tag a Word as a Smi value.
+ Node* SmiTag(Node* value);
+ // Untag a Smi value as a Word.
+ Node* SmiUntag(Node* value);
+
+ // Load a value from the root array.
+ Node* LoadRoot(Heap::RootListIndex root_index);
+
+ // Allocate an object of the given size.
+ Node* Allocate(int size, AllocationFlags flags = kNone);
+ Node* InnerAllocate(Node* previous, int offset);
+
+ // Branching helpers.
+ void BranchIf(Node* condition, Label* if_true, Label* if_false);
+
+#define BRANCH_HELPER(name) \
+ void BranchIf##name(Node* a, Node* b, Label* if_true, Label* if_false) { \
+ BranchIf(name(a, b), if_true, if_false); \
+ }
+ CODE_ASSEMBLER_COMPARE_BINARY_OP_LIST(BRANCH_HELPER)
+#undef BRANCH_HELPER
+
+ // Helpers which delegate to RawMachineAssembler.
+ Factory* factory() const;
+ Isolate* isolate() const;
+ Zone* zone() const;
+
+ protected:
+ // Protected helpers which delegate to RawMachineAssembler.
+ Graph* graph() const;
+
+ Node* SmiShiftBitsConstant();
+
+ // Enables subclasses to perform operations before and after a call.
+ virtual void CallPrologue();
+ virtual void CallEpilogue();
+
+ private:
+ friend class CodeAssemblerTester;
+
+ CodeAssembler(Isolate* isolate, Zone* zone, CallDescriptor* call_descriptor,
+ Code::Flags flags, const char* name);
+
+ Node* CallN(CallDescriptor* descriptor, Node* code_target, Node** args);
+ Node* TailCallN(CallDescriptor* descriptor, Node* code_target, Node** args);
+
+ Node* AllocateRawAligned(Node* size_in_bytes, AllocationFlags flags,
+ Node* top_address, Node* limit_address);
+ Node* AllocateRawUnaligned(Node* size_in_bytes, AllocationFlags flags,
+ Node* top_adddress, Node* limit_address);
+
+ base::SmartPointer<RawMachineAssembler> raw_assembler_;
+ Code::Flags flags_;
+ const char* name_;
+ bool code_generated_;
+ ZoneVector<Variable::Impl*> variables_;
+
+ DISALLOW_COPY_AND_ASSIGN(CodeAssembler);
+};
+
+DEFINE_OPERATORS_FOR_FLAGS(CodeAssembler::AllocationFlags);
+
+class CodeAssembler::Label {
+ public:
+ enum Type { kDeferred, kNonDeferred };
+
+ explicit Label(
+ CodeAssembler* assembler,
+ CodeAssembler::Label::Type type = CodeAssembler::Label::kNonDeferred)
+ : CodeAssembler::Label(assembler, 0, nullptr, type) {}
+ Label(CodeAssembler* assembler, CodeAssembler::Variable* merged_variable,
+ CodeAssembler::Label::Type type = CodeAssembler::Label::kNonDeferred)
+ : CodeAssembler::Label(assembler, 1, &merged_variable, type) {}
+ Label(CodeAssembler* assembler, int merged_variable_count,
+ CodeAssembler::Variable** merged_variables,
+ CodeAssembler::Label::Type type = CodeAssembler::Label::kNonDeferred);
+ ~Label() {}
+
+ private:
+ friend class CodeAssembler;
+
+ void Bind();
+ void MergeVariables();
+
+ bool bound_;
+ size_t merge_count_;
+ CodeAssembler* assembler_;
+ RawMachineLabel* label_;
+ // Map of variables that need to be merged to their phi nodes (or placeholders
+ // for those phis).
+ std::map<Variable::Impl*, Node*> variable_phis_;
+ // Map of variables to the list of value nodes that have been added from each
+ // merge path in their order of merging.
+ std::map<Variable::Impl*, std::vector<Node*>> variable_merges_;
+};
+
+} // namespace compiler
+} // namespace internal
+} // namespace v8
+
+#endif // V8_COMPILER_CODE_ASSEMBLER_H_
« no previous file with comments | « src/code-stubs.cc ('k') | src/compiler/code-assembler.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698