[vm interpreter] Remove intrinsics code as 'Intrinsic' bytecode is not used.
Change-Id: I9590bea15eeacafc32e3f31cfb5a41243556f979 Reviewed-on: https://dart-review.googlesource.com/c/87720 Reviewed-by: Alexander Markov <alexmarkov@google.com> Commit-Queue: Régis Crelier <regis@google.com>
This commit is contained in:
committed by
commit-bot@chromium.org
parent
5a0dd76be0
commit
9c8d627347
@@ -134,38 +134,6 @@ class InterpreterHelpers {
|
||||
*reinterpret_cast<intptr_t*>(&entries[offset + count_offset]) = raw_smi_new;
|
||||
}
|
||||
|
||||
DART_FORCE_INLINE static bool IsStrictEqualWithNumberCheck(RawObject* lhs,
|
||||
RawObject* rhs) {
|
||||
if (lhs == rhs) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (lhs->IsHeapObject() && rhs->IsHeapObject()) {
|
||||
const intptr_t lhs_cid = lhs->GetClassId();
|
||||
const intptr_t rhs_cid = rhs->GetClassId();
|
||||
if (lhs_cid == rhs_cid) {
|
||||
switch (lhs_cid) {
|
||||
case kDoubleCid:
|
||||
return (bit_cast<uint64_t, double>(
|
||||
static_cast<RawDouble*>(lhs)->ptr()->value_) ==
|
||||
bit_cast<uint64_t, double>(
|
||||
static_cast<RawDouble*>(rhs)->ptr()->value_));
|
||||
|
||||
case kMintCid:
|
||||
return (static_cast<RawMint*>(lhs)->ptr()->value_ ==
|
||||
static_cast<RawMint*>(rhs)->ptr()->value_);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
DART_FORCE_INLINE static T* Untag(T* tagged) {
|
||||
return tagged->ptr();
|
||||
}
|
||||
|
||||
DART_FORCE_INLINE static bool CheckIndex(RawSmi* index, RawSmi* length) {
|
||||
return !index->IsHeapObject() && (reinterpret_cast<intptr_t>(index) >= 0) &&
|
||||
(reinterpret_cast<intptr_t>(index) <
|
||||
@@ -190,303 +158,10 @@ class InterpreterHelpers {
|
||||
Array::element_offset(ArgumentsDescriptor::kPositionalCountIndex)));
|
||||
}
|
||||
|
||||
static bool ObjectArraySetIndexed(Thread* thread,
|
||||
RawObject** FP,
|
||||
RawObject** result) {
|
||||
return ObjectArraySetIndexedUnchecked(thread, FP, result);
|
||||
}
|
||||
|
||||
static bool ObjectArraySetIndexedUnchecked(Thread* thread,
|
||||
RawObject** FP,
|
||||
RawObject** result) {
|
||||
RawObject** args = FrameArguments(FP, 3);
|
||||
RawSmi* index = static_cast<RawSmi*>(args[1]);
|
||||
RawArray* array = static_cast<RawArray*>(args[0]);
|
||||
if (CheckIndex(index, array->ptr()->length_)) {
|
||||
array->StorePointer(array->ptr()->data() + Smi::Value(index), args[2],
|
||||
thread);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
static bool ObjectArrayGetIndexed(Thread* thread,
|
||||
RawObject** FP,
|
||||
RawObject** result) {
|
||||
RawObject** args = FrameArguments(FP, 2);
|
||||
RawSmi* index = static_cast<RawSmi*>(args[1]);
|
||||
RawArray* array = static_cast<RawArray*>(args[0]);
|
||||
if (CheckIndex(index, array->ptr()->length_)) {
|
||||
*result = array->ptr()->data()[Smi::Value(index)];
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
static bool GrowableArraySetIndexed(Thread* thread,
|
||||
RawObject** FP,
|
||||
RawObject** result) {
|
||||
return GrowableArraySetIndexedUnchecked(thread, FP, result);
|
||||
}
|
||||
|
||||
static bool GrowableArraySetIndexedUnchecked(Thread* thread,
|
||||
RawObject** FP,
|
||||
RawObject** result) {
|
||||
RawObject** args = FrameArguments(FP, 3);
|
||||
RawSmi* index = static_cast<RawSmi*>(args[1]);
|
||||
RawGrowableObjectArray* array =
|
||||
static_cast<RawGrowableObjectArray*>(args[0]);
|
||||
if (CheckIndex(index, array->ptr()->length_)) {
|
||||
RawArray* data = array->ptr()->data_;
|
||||
data->StorePointer(data->ptr()->data() + Smi::Value(index), args[2],
|
||||
thread);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
static bool GrowableArrayGetIndexed(Thread* thread,
|
||||
RawObject** FP,
|
||||
RawObject** result) {
|
||||
RawObject** args = FrameArguments(FP, 2);
|
||||
RawSmi* index = static_cast<RawSmi*>(args[1]);
|
||||
RawGrowableObjectArray* array =
|
||||
static_cast<RawGrowableObjectArray*>(args[0]);
|
||||
if (CheckIndex(index, array->ptr()->length_)) {
|
||||
*result = array->ptr()->data_->ptr()->data()[Smi::Value(index)];
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
static bool Double_getIsNan(Thread* thread,
|
||||
RawObject** FP,
|
||||
RawObject** result) {
|
||||
RawObject** args = FrameArguments(FP, 1);
|
||||
RawDouble* d = static_cast<RawDouble*>(args[0]);
|
||||
*result =
|
||||
isnan(d->ptr()->value_) ? Bool::True().raw() : Bool::False().raw();
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool Double_getIsInfinite(Thread* thread,
|
||||
RawObject** FP,
|
||||
RawObject** result) {
|
||||
RawObject** args = FrameArguments(FP, 1);
|
||||
RawDouble* d = static_cast<RawDouble*>(args[0]);
|
||||
*result =
|
||||
isinf(d->ptr()->value_) ? Bool::True().raw() : Bool::False().raw();
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool ObjectEquals(Thread* thread, RawObject** FP, RawObject** result) {
|
||||
RawObject** args = FrameArguments(FP, 2);
|
||||
*result = args[0] == args[1] ? Bool::True().raw() : Bool::False().raw();
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool ObjectRuntimeType(Thread* thread,
|
||||
RawObject** FP,
|
||||
RawObject** result) {
|
||||
RawObject** args = FrameArguments(FP, 1);
|
||||
const intptr_t cid = GetClassId(args[0]);
|
||||
if (cid == kClosureCid) {
|
||||
return false;
|
||||
}
|
||||
if (cid < kNumPredefinedCids) {
|
||||
if (cid == kDoubleCid) {
|
||||
*result = thread->isolate()->object_store()->double_type();
|
||||
return true;
|
||||
} else if (RawObject::IsStringClassId(cid)) {
|
||||
*result = thread->isolate()->object_store()->string_type();
|
||||
return true;
|
||||
} else if (RawObject::IsIntegerClassId(cid)) {
|
||||
*result = thread->isolate()->object_store()->int_type();
|
||||
return true;
|
||||
}
|
||||
}
|
||||
RawClass* cls = thread->isolate()->class_table()->At(cid);
|
||||
if (cls->ptr()->num_type_arguments_ != 0) {
|
||||
return false;
|
||||
}
|
||||
RawType* typ = cls->ptr()->declaration_type_;
|
||||
if (typ == Object::null()) {
|
||||
// Declaration type is not computed yet, intrinsic falls through.
|
||||
return false;
|
||||
}
|
||||
*result = static_cast<RawObject*>(typ);
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool GetDoubleOperands(RawObject** args, double* d1, double* d2) {
|
||||
RawObject* obj2 = args[1];
|
||||
if (!obj2->IsHeapObject()) {
|
||||
*d2 =
|
||||
static_cast<double>(reinterpret_cast<intptr_t>(obj2) >> kSmiTagSize);
|
||||
} else if (obj2->GetClassId() == kDoubleCid) {
|
||||
RawDouble* obj2d = static_cast<RawDouble*>(obj2);
|
||||
*d2 = obj2d->ptr()->value_;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
RawDouble* obj1 = static_cast<RawDouble*>(args[0]);
|
||||
*d1 = obj1->ptr()->value_;
|
||||
return true;
|
||||
}
|
||||
|
||||
static RawObject* AllocateDouble(Thread* thread, double value) {
|
||||
const intptr_t instance_size = Double::InstanceSize();
|
||||
const uword start =
|
||||
thread->heap()->new_space()->TryAllocateInTLAB(thread, instance_size);
|
||||
if (LIKELY(start != 0)) {
|
||||
uword tags = 0;
|
||||
tags = RawObject::ClassIdTag::update(kDoubleCid, tags);
|
||||
tags = RawObject::SizeTag::update(instance_size, tags);
|
||||
tags = RawObject::NewBit::update(true, tags);
|
||||
// Also writes zero in the hash_ field.
|
||||
*reinterpret_cast<uword*>(start + Double::tags_offset()) = tags;
|
||||
*reinterpret_cast<double*>(start + Double::value_offset()) = value;
|
||||
return reinterpret_cast<RawObject*>(start + kHeapObjectTag);
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static bool Double_add(Thread* thread, RawObject** FP, RawObject** result) {
|
||||
double d1, d2;
|
||||
if (!GetDoubleOperands(FrameArguments(FP, 2), &d1, &d2)) {
|
||||
return false;
|
||||
}
|
||||
RawObject* new_double = AllocateDouble(thread, d1 + d2);
|
||||
if (new_double != NULL) {
|
||||
*result = new_double;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
static bool Double_mul(Thread* thread, RawObject** FP, RawObject** result) {
|
||||
double d1, d2;
|
||||
if (!GetDoubleOperands(FrameArguments(FP, 2), &d1, &d2)) {
|
||||
return false;
|
||||
}
|
||||
RawObject* new_double = AllocateDouble(thread, d1 * d2);
|
||||
if (new_double != NULL) {
|
||||
*result = new_double;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
static bool Double_sub(Thread* thread, RawObject** FP, RawObject** result) {
|
||||
double d1, d2;
|
||||
if (!GetDoubleOperands(FrameArguments(FP, 2), &d1, &d2)) {
|
||||
return false;
|
||||
}
|
||||
RawObject* new_double = AllocateDouble(thread, d1 - d2);
|
||||
if (new_double != NULL) {
|
||||
*result = new_double;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
static bool Double_div(Thread* thread, RawObject** FP, RawObject** result) {
|
||||
double d1, d2;
|
||||
if (!GetDoubleOperands(FrameArguments(FP, 2), &d1, &d2)) {
|
||||
return false;
|
||||
}
|
||||
RawObject* new_double = AllocateDouble(thread, d1 / d2);
|
||||
if (new_double != NULL) {
|
||||
*result = new_double;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
static bool Double_greaterThan(Thread* thread,
|
||||
RawObject** FP,
|
||||
RawObject** result) {
|
||||
double d1, d2;
|
||||
if (!GetDoubleOperands(FrameArguments(FP, 2), &d1, &d2)) {
|
||||
return false;
|
||||
}
|
||||
*result = d1 > d2 ? Bool::True().raw() : Bool::False().raw();
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool Double_greaterEqualThan(Thread* thread,
|
||||
RawObject** FP,
|
||||
RawObject** result) {
|
||||
double d1, d2;
|
||||
if (!GetDoubleOperands(FrameArguments(FP, 2), &d1, &d2)) {
|
||||
return false;
|
||||
}
|
||||
*result = d1 >= d2 ? Bool::True().raw() : Bool::False().raw();
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool Double_lessThan(Thread* thread,
|
||||
RawObject** FP,
|
||||
RawObject** result) {
|
||||
double d1, d2;
|
||||
if (!GetDoubleOperands(FrameArguments(FP, 2), &d1, &d2)) {
|
||||
return false;
|
||||
}
|
||||
*result = d1 < d2 ? Bool::True().raw() : Bool::False().raw();
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool Double_equal(Thread* thread, RawObject** FP, RawObject** result) {
|
||||
double d1, d2;
|
||||
if (!GetDoubleOperands(FrameArguments(FP, 2), &d1, &d2)) {
|
||||
return false;
|
||||
}
|
||||
*result = d1 == d2 ? Bool::True().raw() : Bool::False().raw();
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool Double_lessEqualThan(Thread* thread,
|
||||
RawObject** FP,
|
||||
RawObject** result) {
|
||||
double d1, d2;
|
||||
if (!GetDoubleOperands(FrameArguments(FP, 2), &d1, &d2)) {
|
||||
return false;
|
||||
}
|
||||
*result = d1 <= d2 ? Bool::True().raw() : Bool::False().raw();
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool ClearAsyncThreadStack(Thread* thread,
|
||||
RawObject** FP,
|
||||
RawObject** result) {
|
||||
thread->clear_async_stack_trace();
|
||||
*result = Object::null();
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool SetAsyncThreadStackTrace(Thread* thread,
|
||||
RawObject** FP,
|
||||
RawObject** result) {
|
||||
RawObject** args = FrameArguments(FP, 1);
|
||||
thread->set_raw_async_stack_trace(
|
||||
reinterpret_cast<RawStackTrace*>(args[0]));
|
||||
*result = Object::null();
|
||||
return true;
|
||||
}
|
||||
|
||||
DART_FORCE_INLINE static RawBytecode* FrameBytecode(RawObject** FP) {
|
||||
ASSERT(GetClassId(FP[kKBCPcMarkerSlotFromFp]) == kBytecodeCid);
|
||||
return static_cast<RawBytecode*>(FP[kKBCPcMarkerSlotFromFp]);
|
||||
}
|
||||
|
||||
DART_FORCE_INLINE static uint8_t* GetTypedData(RawObject* obj,
|
||||
RawObject* index) {
|
||||
ASSERT(RawObject::IsTypedDataClassId(obj->GetClassId()));
|
||||
RawTypedData* array = reinterpret_cast<RawTypedData*>(obj);
|
||||
const intptr_t byte_offset = Smi::Value(RAW_CAST(Smi, index));
|
||||
ASSERT(byte_offset >= 0);
|
||||
return array->ptr()->data() + byte_offset;
|
||||
}
|
||||
};
|
||||
|
||||
DART_FORCE_INLINE static uint32_t* SavedCallerPC(RawObject** FP) {
|
||||
@@ -560,51 +235,6 @@ void LookupCache::Insert(intptr_t receiver_cid,
|
||||
entries_[probe1].target = target;
|
||||
}
|
||||
|
||||
IntrinsicHandler Interpreter::intrinsics_[Interpreter::kIntrinsicCount];
|
||||
|
||||
// Synchronization primitives support.
|
||||
void Interpreter::InitOnce() {
|
||||
for (intptr_t i = 0; i < kIntrinsicCount; i++) {
|
||||
intrinsics_[i] = 0;
|
||||
}
|
||||
|
||||
intrinsics_[kObjectArraySetIndexedIntrinsic] =
|
||||
InterpreterHelpers::ObjectArraySetIndexed;
|
||||
intrinsics_[kObjectArraySetIndexedUncheckedIntrinsic] =
|
||||
InterpreterHelpers::ObjectArraySetIndexedUnchecked;
|
||||
intrinsics_[kObjectArrayGetIndexedIntrinsic] =
|
||||
InterpreterHelpers::ObjectArrayGetIndexed;
|
||||
intrinsics_[kGrowableArraySetIndexedIntrinsic] =
|
||||
InterpreterHelpers::GrowableArraySetIndexed;
|
||||
intrinsics_[kGrowableArraySetIndexedUncheckedIntrinsic] =
|
||||
InterpreterHelpers::GrowableArraySetIndexedUnchecked;
|
||||
intrinsics_[kGrowableArrayGetIndexedIntrinsic] =
|
||||
InterpreterHelpers::GrowableArrayGetIndexed;
|
||||
intrinsics_[kObjectEqualsIntrinsic] = InterpreterHelpers::ObjectEquals;
|
||||
intrinsics_[kObjectRuntimeTypeIntrinsic] =
|
||||
InterpreterHelpers::ObjectRuntimeType;
|
||||
|
||||
intrinsics_[kDouble_getIsNaNIntrinsic] = InterpreterHelpers::Double_getIsNan;
|
||||
intrinsics_[kDouble_getIsInfiniteIntrinsic] =
|
||||
InterpreterHelpers::Double_getIsInfinite;
|
||||
intrinsics_[kDouble_addIntrinsic] = InterpreterHelpers::Double_add;
|
||||
intrinsics_[kDouble_mulIntrinsic] = InterpreterHelpers::Double_mul;
|
||||
intrinsics_[kDouble_subIntrinsic] = InterpreterHelpers::Double_sub;
|
||||
intrinsics_[kDouble_divIntrinsic] = InterpreterHelpers::Double_div;
|
||||
intrinsics_[kDouble_greaterThanIntrinsic] =
|
||||
InterpreterHelpers::Double_greaterThan;
|
||||
intrinsics_[kDouble_greaterEqualThanIntrinsic] =
|
||||
InterpreterHelpers::Double_greaterEqualThan;
|
||||
intrinsics_[kDouble_lessThanIntrinsic] = InterpreterHelpers::Double_lessThan;
|
||||
intrinsics_[kDouble_equalIntrinsic] = InterpreterHelpers::Double_equal;
|
||||
intrinsics_[kDouble_lessEqualThanIntrinsic] =
|
||||
InterpreterHelpers::Double_lessEqualThan;
|
||||
intrinsics_[kClearAsyncThreadStackTraceIntrinsic] =
|
||||
InterpreterHelpers::ClearAsyncThreadStack;
|
||||
intrinsics_[kSetAsyncThreadStackTraceIntrinsic] =
|
||||
InterpreterHelpers::SetAsyncThreadStackTrace;
|
||||
}
|
||||
|
||||
Interpreter::Interpreter()
|
||||
: stack_(NULL), fp_(NULL), pp_(NULL), argdesc_(NULL), lookup_cache_() {
|
||||
// Setup interpreter support first. Some of this information is needed to
|
||||
@@ -2445,7 +2075,6 @@ SwitchDispatch:
|
||||
DISPATCH();
|
||||
}
|
||||
|
||||
// Return and return like instructions (Intrinsic).
|
||||
{
|
||||
RawObject* result; // result to return to the caller.
|
||||
|
||||
|
||||
@@ -94,9 +94,6 @@ class Interpreter {
|
||||
// Identify an entry frame by looking at its pc marker value.
|
||||
static bool IsEntryFrameMarker(uword pc) { return (pc & 2) != 0; }
|
||||
|
||||
// Call on program start.
|
||||
static void InitOnce();
|
||||
|
||||
RawObject* Call(const Function& function,
|
||||
const Array& arguments_descriptor,
|
||||
const Array& arguments,
|
||||
@@ -114,18 +111,6 @@ class Interpreter {
|
||||
uword get_fp() const { return reinterpret_cast<uword>(fp_); }
|
||||
uword get_pc() const { return pc_; }
|
||||
|
||||
enum IntrinsicId {
|
||||
#define V(test_class_name, test_function_name, enum_name, fp) \
|
||||
k##enum_name##Intrinsic,
|
||||
ALL_INTRINSICS_LIST(V) GRAPH_INTRINSICS_LIST(V)
|
||||
#undef V
|
||||
kIntrinsicCount,
|
||||
};
|
||||
|
||||
static bool IsSupportedIntrinsic(IntrinsicId id) {
|
||||
return intrinsics_[id] != NULL;
|
||||
}
|
||||
|
||||
void VisitObjectPointers(ObjectPointerVisitor* visitor);
|
||||
void MajorGC() { lookup_cache_.Clear(); }
|
||||
|
||||
@@ -148,8 +133,6 @@ class Interpreter {
|
||||
|
||||
LookupCache lookup_cache_;
|
||||
|
||||
static IntrinsicHandler intrinsics_[kIntrinsicCount];
|
||||
|
||||
void Exit(Thread* thread,
|
||||
RawObject** base,
|
||||
RawObject** exit_frame,
|
||||
|
||||
Reference in New Issue
Block a user