summaryrefslogtreecommitdiff
path: root/chromium/v8/src/compiler/code-assembler.h
diff options
context:
space:
mode:
Diffstat (limited to 'chromium/v8/src/compiler/code-assembler.h')
-rw-r--r--chromium/v8/src/compiler/code-assembler.h189
1 files changed, 169 insertions, 20 deletions
diff --git a/chromium/v8/src/compiler/code-assembler.h b/chromium/v8/src/compiler/code-assembler.h
index 3a5f06bb955..1a574738e7d 100644
--- a/chromium/v8/src/compiler/code-assembler.h
+++ b/chromium/v8/src/compiler/code-assembler.h
@@ -18,6 +18,7 @@
#include "src/heap/heap.h"
#include "src/machine-type.h"
#include "src/objects.h"
+#include "src/objects/arguments.h"
#include "src/objects/data-handler.h"
#include "src/objects/map.h"
#include "src/objects/maybe-object.h"
@@ -27,11 +28,16 @@
namespace v8 {
namespace internal {
+// Forward declarations.
+class AsmWasmData;
+class AsyncGeneratorRequest;
+class BigInt;
class CallInterfaceDescriptor;
class Callable;
class Factory;
class InterpreterData;
class Isolate;
+class JSAsyncFunctionObject;
class JSAsyncGeneratorObject;
class JSCollator;
class JSCollection;
@@ -42,10 +48,15 @@ class JSNumberFormat;
class JSPluralRules;
class JSRegExpStringIterator;
class JSRelativeTimeFormat;
+class JSSegmentIterator;
class JSSegmenter;
class JSV8BreakIterator;
+class JSWeakCell;
class JSWeakCollection;
+class JSWeakFactory;
+class JSWeakFactoryCleanupIterator;
class JSWeakMap;
+class JSWeakRef;
class JSWeakSet;
class MaybeObject;
class PromiseCapability;
@@ -53,7 +64,7 @@ class PromiseFulfillReactionJobTask;
class PromiseReaction;
class PromiseReactionJobTask;
class PromiseRejectReactionJobTask;
-class TorqueAssembler;
+class WeakFactoryCleanupJobTask;
class Zone;
template <typename T>
@@ -153,16 +164,20 @@ struct MachineTypeOf<Smi> {
static constexpr MachineType value = MachineType::TaggedSigned();
};
template <class HeapObjectSubtype>
-struct MachineTypeOf<HeapObjectSubtype,
- typename std::enable_if<std::is_base_of<
- HeapObject, HeapObjectSubtype>::value>::type> {
+struct MachineTypeOf<
+ HeapObjectSubtype,
+ typename std::enable_if<
+ std::is_base_of<HeapObject, HeapObjectSubtype>::value ||
+ std::is_base_of<HeapObjectPtr, HeapObjectSubtype>::value>::type> {
static constexpr MachineType value = MachineType::TaggedPointer();
};
template <class HeapObjectSubtype>
constexpr MachineType MachineTypeOf<
- HeapObjectSubtype, typename std::enable_if<std::is_base_of<
- HeapObject, HeapObjectSubtype>::value>::type>::value;
+ HeapObjectSubtype,
+ typename std::enable_if<
+ std::is_base_of<HeapObject, HeapObjectSubtype>::value ||
+ std::is_base_of<HeapObjectPtr, HeapObjectSubtype>::value>::type>::value;
template <class Type, class Enable = void>
struct MachineRepresentationOf {
@@ -176,6 +191,12 @@ struct MachineRepresentationOf<
};
template <class T>
struct MachineRepresentationOf<
+ T, typename std::enable_if<std::is_base_of<ObjectPtr, T>::value>::type> {
+ static const MachineRepresentation value =
+ MachineTypeOf<T>::value.representation();
+};
+template <class T>
+struct MachineRepresentationOf<
T, typename std::enable_if<std::is_base_of<MaybeObject, T>::value>::type> {
static const MachineRepresentation value =
MachineTypeOf<T>::value.representation();
@@ -184,10 +205,12 @@ struct MachineRepresentationOf<
template <class T>
struct is_valid_type_tag {
static const bool value = std::is_base_of<Object, T>::value ||
+ std::is_base_of<ObjectPtr, T>::value ||
std::is_base_of<UntaggedT, T>::value ||
std::is_base_of<MaybeObject, T>::value ||
std::is_same<ExternalReference, T>::value;
static const bool is_tagged = std::is_base_of<Object, T>::value ||
+ std::is_base_of<ObjectPtr, T>::value ||
std::is_base_of<MaybeObject, T>::value;
};
@@ -224,6 +247,24 @@ struct UnionT {
using Number = UnionT<Smi, HeapNumber>;
using Numeric = UnionT<Number, BigInt>;
+class int31_t {
+ public:
+ int31_t() : value_(0) {}
+ int31_t(int value) : value_(value) { // NOLINT(runtime/explicit)
+ DCHECK_EQ((value & 0x80000000) != 0, (value & 0x40000000) != 0);
+ }
+ int31_t& operator=(int value) {
+ DCHECK_EQ((value & 0x80000000) != 0, (value & 0x40000000) != 0);
+ value_ = value;
+ return *this;
+ }
+ int32_t value() const { return value_; }
+ operator int32_t() const { return value_; }
+
+ private:
+ int32_t value_;
+};
+
#define ENUM_ELEMENT(Name) k##Name,
#define ENUM_STRUCT_ELEMENT(NAME, Name, name) k##Name,
enum class ObjectType {
@@ -241,6 +282,7 @@ class BooleanWrapper;
class CompilationCacheTable;
class Constructor;
class Filler;
+class FunctionTemplateRareData;
class InternalizedString;
class JSArgumentsObject;
class JSContextExtensionObject;
@@ -290,7 +332,10 @@ HEAP_OBJECT_TEMPLATE_TYPE_LIST(OBJECT_TYPE_TEMPLATE_CASE)
#undef OBJECT_TYPE_STRUCT_CASE
#undef OBJECT_TYPE_TEMPLATE_CASE
-Smi* CheckObjectType(Object* value, Smi* type, String* location);
+// {raw_type} must be a tagged Smi.
+// {raw_location} must be a tagged String.
+// Returns a tagged Smi.
+Address CheckObjectType(Object* value, Address raw_type, Address raw_location);
namespace compiler {
@@ -308,9 +353,20 @@ typedef ZoneVector<CodeAssemblerVariable*> CodeAssemblerVariableList;
typedef std::function<void()> CodeAssemblerCallback;
+// TODO(3770): The HeapObject/HeapObjectPtr dance is temporary (while the
+// incremental transition is in progress, we want to pretend that subclasses
+// of HeapObjectPtr are also subclasses of Object/HeapObject); it can be
+// removed when the migration is complete.
template <class T, class U>
struct is_subtype {
- static const bool value = std::is_base_of<U, T>::value;
+ static const bool value = std::is_base_of<U, T>::value ||
+ (std::is_base_of<U, HeapObject>::value &&
+ std::is_base_of<HeapObjectPtr, T>::value);
+};
+// TODO(3770): Temporary; remove after migration.
+template <>
+struct is_subtype<Smi, Object> {
+ static const bool value = true;
};
template <class T1, class T2, class U>
struct is_subtype<UnionT<T1, T2>, U> {
@@ -389,6 +445,7 @@ struct types_have_common_values<MaybeObject, T> {
// TNode<T> is an SSA value with the static type tag T, which is one of the
// following:
// - a subclass of internal::Object represents a tagged type
+// - a subclass of internal::ObjectPtr represents a tagged type
// - a subclass of internal::UntaggedT represents an untagged type
// - ExternalReference
// - PairT<T1, T2> for an operation returning two values, with types T1
@@ -436,6 +493,9 @@ class SloppyTNode : public TNode<T> {
: TNode<T>(other) {}
};
+template <class... Types>
+class CodeAssemblerParameterizedLabel;
+
// This macro alias allows to use PairT<T1, T2> as a macro argument.
#define PAIR_TYPE(T1, T2) PairT<T1, T2>
@@ -624,7 +684,8 @@ class V8_EXPORT_PRIVATE CodeAssembler {
static_assert(types_have_common_values<A, PreviousType>::value,
"Incompatible types: this cast can never succeed.");
- static_assert(std::is_convertible<TNode<A>, TNode<Object>>::value,
+ static_assert(std::is_convertible<TNode<A>, TNode<Object>>::value ||
+ std::is_convertible<TNode<A>, TNode<ObjectPtr>>::value,
"Coercion to untagged values cannot be "
"checked.");
static_assert(
@@ -697,8 +758,11 @@ class V8_EXPORT_PRIVATE CodeAssembler {
#define TO_STRING_LITERAL(x) STRINGIFY(x)
#define CAST(x) \
Cast(x, "CAST(" #x ") at " __FILE__ ":" TO_STRING_LITERAL(__LINE__))
+#define TORQUE_CAST(x) \
+ ca_.Cast(x, "CAST(" #x ") at " __FILE__ ":" TO_STRING_LITERAL(__LINE__))
#else
#define CAST(x) Cast(x)
+#define TORQUE_CAST(x) ca_.Cast(x)
#endif
#ifdef DEBUG
@@ -716,7 +780,7 @@ class V8_EXPORT_PRIVATE CodeAssembler {
return Unsigned(IntPtrConstant(bit_cast<intptr_t>(value)));
}
TNode<Number> NumberConstant(double value);
- TNode<Smi> SmiConstant(Smi* value);
+ TNode<Smi> SmiConstant(Smi value);
TNode<Smi> SmiConstant(int value);
template <typename E,
typename = typename std::enable_if<std::is_enum<E>::value>::type>
@@ -744,9 +808,11 @@ class V8_EXPORT_PRIVATE CodeAssembler {
return value ? Int32TrueConstant() : Int32FalseConstant();
}
+ // TODO(jkummerow): The style guide wants pointers for output parameters.
+ // https://google.github.io/styleguide/cppguide.html#Output_Parameters
bool ToInt32Constant(Node* node, int32_t& out_value);
bool ToInt64Constant(Node* node, int64_t& out_value);
- bool ToSmiConstant(Node* node, Smi*& out_value);
+ bool ToSmiConstant(Node* node, Smi* out_value);
bool ToIntPtrConstant(Node* node, intptr_t& out_value);
bool IsUndefinedConstant(TNode<Object> node);
@@ -791,6 +857,31 @@ class V8_EXPORT_PRIVATE CodeAssembler {
void Branch(SloppyTNode<IntegralT> condition, Label* true_label,
Label* false_label);
+ template <class T>
+ TNode<T> Uninitialized() {
+ return {};
+ }
+
+ template <class... T>
+ void Bind(CodeAssemblerParameterizedLabel<T...>* label, TNode<T>*... phis) {
+ Bind(label->plain_label());
+ label->CreatePhis(phis...);
+ }
+ template <class... T, class... Args>
+ void Branch(TNode<BoolT> condition,
+ CodeAssemblerParameterizedLabel<T...>* if_true,
+ CodeAssemblerParameterizedLabel<T...>* if_false, Args... args) {
+ if_true->AddInputs(args...);
+ if_false->AddInputs(args...);
+ Branch(condition, if_true->plain_label(), if_false->plain_label());
+ }
+
+ template <class... T, class... Args>
+ void Goto(CodeAssemblerParameterizedLabel<T...>* label, Args... args) {
+ label->AddInputs(args...);
+ Goto(label->plain_label());
+ }
+
void Branch(TNode<BoolT> condition, const std::function<void()>& true_body,
const std::function<void()>& false_body);
void Branch(TNode<BoolT> condition, Label* true_label,
@@ -878,16 +969,23 @@ class V8_EXPORT_PRIVATE CodeAssembler {
return UncheckedCast<IntPtrT>(
WordShr(static_cast<Node*>(left), static_cast<Node*>(right)));
}
+ TNode<IntPtrT> WordSar(TNode<IntPtrT> left, TNode<IntegralT> right) {
+ return UncheckedCast<IntPtrT>(
+ WordSar(static_cast<Node*>(left), static_cast<Node*>(right)));
+ }
TNode<IntPtrT> WordAnd(TNode<IntPtrT> left, TNode<IntPtrT> right) {
return UncheckedCast<IntPtrT>(
WordAnd(static_cast<Node*>(left), static_cast<Node*>(right)));
}
+ // TODO(3770): Drop ObjectPtr when the transition is done.
template <class Left, class Right,
class = typename std::enable_if<
- std::is_base_of<Object, Left>::value &&
- std::is_base_of<Object, Right>::value>::type>
+ (std::is_base_of<Object, Left>::value ||
+ std::is_base_of<ObjectPtr, Left>::value) &&
+ (std::is_base_of<Object, Right>::value ||
+ std::is_base_of<ObjectPtr, Right>::value)>::type>
TNode<BoolT> WordEqual(TNode<Left> left, TNode<Right> right) {
return WordEqual(ReinterpretCast<WordT>(left),
ReinterpretCast<WordT>(right));
@@ -902,8 +1000,10 @@ class V8_EXPORT_PRIVATE CodeAssembler {
}
template <class Left, class Right,
class = typename std::enable_if<
- std::is_base_of<Object, Left>::value &&
- std::is_base_of<Object, Right>::value>::type>
+ (std::is_base_of<Object, Left>::value ||
+ std::is_base_of<ObjectPtr, Left>::value) &&
+ (std::is_base_of<Object, Right>::value ||
+ std::is_base_of<ObjectPtr, Right>::value)>::type>
TNode<BoolT> WordNotEqual(TNode<Left> left, TNode<Right> right) {
return WordNotEqual(ReinterpretCast<WordT>(left),
ReinterpretCast<WordT>(right));
@@ -940,6 +1040,7 @@ class V8_EXPORT_PRIVATE CodeAssembler {
}
TNode<WordT> IntPtrAdd(SloppyTNode<WordT> left, SloppyTNode<WordT> right);
+ TNode<IntPtrT> IntPtrDiv(TNode<IntPtrT> left, TNode<IntPtrT> right);
TNode<WordT> IntPtrSub(SloppyTNode<WordT> left, SloppyTNode<WordT> right);
TNode<WordT> IntPtrMul(SloppyTNode<WordT> left, SloppyTNode<WordT> right);
TNode<IntPtrT> IntPtrAdd(TNode<IntPtrT> left, TNode<IntPtrT> right) {
@@ -969,6 +1070,9 @@ class V8_EXPORT_PRIVATE CodeAssembler {
TNode<IntPtrT> WordShr(TNode<IntPtrT> value, int shift) {
return UncheckedCast<IntPtrT>(WordShr(static_cast<Node*>(value), shift));
}
+ TNode<IntPtrT> WordSar(TNode<IntPtrT> value, int shift) {
+ return UncheckedCast<IntPtrT>(WordSar(static_cast<Node*>(value), shift));
+ }
TNode<Word32T> Word32Shr(SloppyTNode<Word32T> value, int shift);
TNode<WordT> WordOr(SloppyTNode<WordT> left, SloppyTNode<WordT> right);
@@ -1245,6 +1349,8 @@ class V8_EXPORT_PRIVATE CodeAssembler {
bool UnalignedLoadSupported(MachineRepresentation rep) const;
bool UnalignedStoreSupported(MachineRepresentation rep) const;
+ bool IsExceptionHandlerActive() const;
+
protected:
void RegisterCallGenerationCallbacks(
const CodeAssemblerCallback& call_prologue,
@@ -1257,6 +1363,8 @@ class V8_EXPORT_PRIVATE CodeAssembler {
bool IsJSFunctionCall() const;
private:
+ void HandleException(Node* result);
+
TNode<Object> CallRuntimeImpl(Runtime::FunctionId function,
TNode<Object> context,
std::initializer_list<TNode<Object>> args);
@@ -1328,6 +1436,10 @@ class CodeAssemblerVariable {
friend class CodeAssemblerState;
friend std::ostream& operator<<(std::ostream&, const Impl&);
friend std::ostream& operator<<(std::ostream&, const CodeAssemblerVariable&);
+ struct ImplComparator {
+ bool operator()(const CodeAssemblerVariable::Impl* a,
+ const CodeAssemblerVariable::Impl* b) const;
+ };
Impl* impl_;
CodeAssemblerState* state_;
DISALLOW_COPY_AND_ASSIGN(CodeAssemblerVariable);
@@ -1417,10 +1529,14 @@ class CodeAssemblerLabel {
RawMachineLabel* label_;
// Map of variables that need to be merged to their phi nodes (or placeholders
// for those phis).
- std::map<CodeAssemblerVariable::Impl*, Node*> variable_phis_;
+ std::map<CodeAssemblerVariable::Impl*, Node*,
+ CodeAssemblerVariable::ImplComparator>
+ 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<CodeAssemblerVariable::Impl*, std::vector<Node*>> variable_merges_;
+ std::map<CodeAssemblerVariable::Impl*, std::vector<Node*>,
+ CodeAssemblerVariable::ImplComparator>
+ variable_merges_;
};
class CodeAssemblerParameterizedLabelBase {
@@ -1457,7 +1573,7 @@ class CodeAssemblerParameterizedLabel
: CodeAssemblerParameterizedLabelBase(assembler, kArity, type) {}
private:
- friend class internal::TorqueAssembler;
+ friend class CodeAssembler;
void AddInputs(TNode<Types>... inputs) {
CodeAssemblerParameterizedLabelBase::AddInputs(
@@ -1477,6 +1593,9 @@ class CodeAssemblerParameterizedLabel
}
};
+typedef CodeAssemblerParameterizedLabel<Object>
+ CodeAssemblerExceptionHandlerLabel;
+
class V8_EXPORT_PRIVATE CodeAssemblerState {
public:
// Create with CallStub linkage.
@@ -1501,8 +1620,8 @@ class V8_EXPORT_PRIVATE CodeAssemblerState {
#if DEBUG
void PrintCurrentBlock(std::ostream& os);
- bool InsideBlock();
#endif // DEBUG
+ bool InsideBlock();
void SetInitialDebugInformation(const char* msg, const char* file, int line);
private:
@@ -1511,25 +1630,55 @@ class V8_EXPORT_PRIVATE CodeAssemblerState {
friend class CodeAssemblerVariable;
friend class CodeAssemblerTester;
friend class CodeAssemblerParameterizedLabelBase;
+ friend class CodeAssemblerScopedExceptionHandler;
CodeAssemblerState(Isolate* isolate, Zone* zone,
CallDescriptor* call_descriptor, Code::Kind kind,
const char* name, PoisoningMitigationLevel poisoning_level,
uint32_t stub_key, int32_t builtin_index);
+ void PushExceptionHandler(CodeAssemblerExceptionHandlerLabel* label);
+ void PopExceptionHandler();
+
std::unique_ptr<RawMachineAssembler> raw_assembler_;
Code::Kind kind_;
const char* name_;
uint32_t stub_key_;
int32_t builtin_index_;
bool code_generated_;
- ZoneSet<CodeAssemblerVariable::Impl*> variables_;
+ ZoneSet<CodeAssemblerVariable::Impl*, CodeAssemblerVariable::ImplComparator>
+ variables_;
CodeAssemblerCallback call_prologue_;
CodeAssemblerCallback call_epilogue_;
+ std::vector<CodeAssemblerExceptionHandlerLabel*> exception_handler_labels_;
+ typedef uint32_t VariableId;
+ VariableId next_variable_id_ = 0;
+ VariableId NextVariableId() { return next_variable_id_++; }
DISALLOW_COPY_AND_ASSIGN(CodeAssemblerState);
};
+class CodeAssemblerScopedExceptionHandler {
+ public:
+ CodeAssemblerScopedExceptionHandler(
+ CodeAssembler* assembler, CodeAssemblerExceptionHandlerLabel* label);
+
+ // Use this constructor for compatability/ports of old CSA code only. New code
+ // should use the CodeAssemblerExceptionHandlerLabel version.
+ CodeAssemblerScopedExceptionHandler(
+ CodeAssembler* assembler, CodeAssemblerLabel* label,
+ TypedCodeAssemblerVariable<Object>* exception);
+
+ ~CodeAssemblerScopedExceptionHandler();
+
+ private:
+ bool has_handler_;
+ CodeAssembler* assembler_;
+ CodeAssemblerLabel* compatibility_label_;
+ std::unique_ptr<CodeAssemblerExceptionHandlerLabel> label_;
+ TypedCodeAssemblerVariable<Object>* exception_;
+};
+
} // namespace compiler
} // namespace internal
} // namespace v8