#endif // V8_HOST_CAN_READ_UNALIGNED
}
+static inline simd128_value_t read_simd128_value(Address p) {
+ return *reinterpret_cast<simd128_value_t*>(p);
+}
class FrameDescription;
class TranslationIterator;
};
+template<typename T>
+class SIMD128MaterializationDescriptor BASE_EMBEDDED {
+ public:
+ SIMD128MaterializationDescriptor(T destination, simd128_value_t value)
+ : destination_(destination), value_(value) { }
+
+ T destination() const { return destination_; }
+ simd128_value_t value() const { return value_; }
+
+ private:
+ T destination_;
+ simd128_value_t value_;
+};
+
+
class ObjectMaterializationDescriptor BASE_EMBEDDED {
public:
ObjectMaterializationDescriptor(
void AddObjectDuplication(intptr_t slot, int object_index);
void AddObjectTaggedValue(intptr_t value);
void AddObjectDoubleValue(double value);
+ void AddObjectSIMD128Value(simd128_value_t value, int translation_opcode);
void AddDoubleValue(intptr_t slot_address, double value);
+ void AddSIMD128Value(intptr_t slot_address, simd128_value_t value,
+ int translation_opcode);
bool ArgumentsObjectIsAdapted(int object_index) {
ObjectMaterializationDescriptor desc = deferred_objects_.at(object_index);
void SetPlatformCompiledStubRegisters(FrameDescription* output_frame,
CodeStubInterfaceDescriptor* desc);
- // Fill the given output frame's double registers with the original values
- // from the input frame's double registers.
- void CopyDoubleRegisters(FrameDescription* output_frame);
+ // Fill the given output frame's simd128 registers with the original values
+ // from the input frame's simd128 registers.
+ void CopySIMD128Registers(FrameDescription* output_frame);
// Determines whether the input frame contains alignment padding by looking
// at the dynamic alignment state slot inside the frame.
List<Object*> deferred_objects_tagged_values_;
List<HeapNumberMaterializationDescriptor<int> >
deferred_objects_double_values_;
+ List<SIMD128MaterializationDescriptor<int> >
+ deferred_objects_float32x4_values_;
+ List<SIMD128MaterializationDescriptor<int> >
+ deferred_objects_int32x4_values_;
List<ObjectMaterializationDescriptor> deferred_objects_;
List<HeapNumberMaterializationDescriptor<Address> > deferred_heap_numbers_;
+ List<SIMD128MaterializationDescriptor<Address> > deferred_float32x4s_;
+ List<SIMD128MaterializationDescriptor<Address> > deferred_int32x4s_;
+
+ // Key for lookup of previously materialized objects
+ Address stack_fp_;
+ Handle<FixedArray> previously_materialized_objects_;
+ int prev_materialized_count_;
// Output frame information. Only used during heap object materialization.
List<Handle<JSFunction> > jsframe_functions_;
return read_double_value(reinterpret_cast<Address>(ptr));
}
+ simd128_value_t GetSIMD128FrameSlot(unsigned offset) {
+ intptr_t* ptr = GetFrameSlotPointer(offset);
+ return read_simd128_value(reinterpret_cast<Address>(ptr));
+ }
+
void SetFrameSlot(unsigned offset, intptr_t value) {
*GetFrameSlotPointer(offset) = value;
}
return registers_[n];
}
- double GetDoubleRegister(unsigned n) const {
- ASSERT(n < ARRAY_SIZE(double_registers_));
- return double_registers_[n];
+ double GetDoubleRegister(unsigned n) const;
+
+ simd128_value_t GetSIMD128Register(unsigned n) const {
+ ASSERT(n < ARRAY_SIZE(simd128_registers_));
+ return simd128_registers_[n];
}
void SetRegister(unsigned n, intptr_t value) {
registers_[n] = value;
}
- void SetDoubleRegister(unsigned n, double value) {
- ASSERT(n < ARRAY_SIZE(double_registers_));
- double_registers_[n] = value;
+ void SetDoubleRegister(unsigned n, double value);
+
+ void SetSIMD128Register(unsigned n, simd128_value_t value) {
+ ASSERT(n < ARRAY_SIZE(simd128_registers_));
+ simd128_registers_[n] = value;
}
intptr_t GetTop() const { return top_; }
return OFFSET_OF(FrameDescription, registers_);
}
- static int double_registers_offset() {
- return OFFSET_OF(FrameDescription, double_registers_);
+ static int simd128_registers_offset() {
+ return OFFSET_OF(FrameDescription, simd128_registers_);
}
static int frame_size_offset() {
uintptr_t frame_size_; // Number of bytes.
JSFunction* function_;
intptr_t registers_[Register::kNumRegisters];
- double double_registers_[DoubleRegister::kMaxNumRegisters];
+ simd128_value_t simd128_registers_[SIMD128Register::kMaxNumRegisters];
intptr_t top_;
intptr_t pc_;
intptr_t fp_;
V(INT32_REGISTER) \
V(UINT32_REGISTER) \
V(DOUBLE_REGISTER) \
+ V(FLOAT32x4_REGISTER) \
+ V(INT32x4_REGISTER) \
V(STACK_SLOT) \
V(INT32_STACK_SLOT) \
V(UINT32_STACK_SLOT) \
V(DOUBLE_STACK_SLOT) \
+ V(FLOAT32x4_STACK_SLOT) \
+ V(INT32x4_STACK_SLOT) \
V(LITERAL)
void StoreInt32Register(Register reg);
void StoreUint32Register(Register reg);
void StoreDoubleRegister(DoubleRegister reg);
+ void StoreSIMD128Register(SIMD128Register reg, Opcode opcode);
void StoreStackSlot(int index);
void StoreInt32StackSlot(int index);
void StoreUint32StackSlot(int index);
void StoreDoubleStackSlot(int index);
+ void StoreSIMD128StackSlot(int index, Opcode opcode);
void StoreLiteral(int literal_id);
void StoreArgumentsObject(bool args_known, int args_index, int args_length);
INT32,
UINT32,
DOUBLE,
- LITERAL
+ FLOAT32x4,
+ INT32x4,
+ LITERAL,
+ DEFERRED_OBJECT, // Object captured by the escape analysis.
+ // The number of nested objects can be obtained
+ // with the DeferredObjectLength() method
+ // (the SlotRefs of the nested objects follow
+ // this SlotRef in the depth-first order.)
+ DUPLICATE_OBJECT, // Duplicated object of a deferred object.
+ ARGUMENTS_OBJECT // Arguments object - only used to keep indexing
+ // in sync, it should not be materialized.
};
SlotRef()
SlotRef(Isolate* isolate, Object* literal)
: literal_(literal, isolate), representation_(LITERAL) { }
- Handle<Object> GetValue(Isolate* isolate) {
- switch (representation_) {
- case TAGGED:
- return Handle<Object>(Memory::Object_at(addr_), isolate);
-
- case INT32: {
- int value = Memory::int32_at(addr_);
- if (Smi::IsValid(value)) {
- return Handle<Object>(Smi::FromInt(value), isolate);
- } else {
- return isolate->factory()->NewNumberFromInt(value);
- }
- }
-
- case UINT32: {
- uint32_t value = Memory::uint32_at(addr_);
- if (value <= static_cast<uint32_t>(Smi::kMaxValue)) {
- return Handle<Object>(Smi::FromInt(static_cast<int>(value)), isolate);
- } else {
- return isolate->factory()->NewNumber(static_cast<double>(value));
- }
- }
-
- case DOUBLE: {
- double value = read_double_value(addr_);
- return isolate->factory()->NewNumber(value);
- }
-
- case LITERAL:
- return literal_;
-
- default:
- UNREACHABLE();
- return Handle<Object>::null();
+ static SlotRef NewArgumentsObject(int length) {
+ SlotRef slot;
+ slot.representation_ = ARGUMENTS_OBJECT;
+ slot.deferred_object_length_ = length;
+ return slot;
+ }
+
+ static SlotRef NewDeferredObject(int length) {
+ SlotRef slot;
+ slot.representation_ = DEFERRED_OBJECT;
+ slot.deferred_object_length_ = length;
+ return slot;
+ }
+
+ SlotRepresentation Representation() { return representation_; }
+
+ static SlotRef NewDuplicateObject(int id) {
+ SlotRef slot;
+ slot.representation_ = DUPLICATE_OBJECT;
+ slot.duplicate_object_id_ = id;
+ return slot;
+ }
+
+ int GetChildrenCount() {
+ if (representation_ == DEFERRED_OBJECT ||
+ representation_ == ARGUMENTS_OBJECT) {
+ return deferred_object_length_;
+ } else {
+ return 0;
}
}
- static Vector<SlotRef> ComputeSlotMappingForArguments(
- JavaScriptFrame* frame,
- int inlined_frame_index,
- int formal_parameter_count);
+ int DuplicateObjectId() { return duplicate_object_id_; }
+
+ Handle<Object> GetValue(Isolate* isolate);
private:
Address addr_;
Handle<Object> literal_;
SlotRepresentation representation_;
+ int deferred_object_length_;
+ int duplicate_object_id_;
+};
+
+class SlotRefValueBuilder BASE_EMBEDDED {
+ public:
+ SlotRefValueBuilder(
+ JavaScriptFrame* frame,
+ int inlined_frame_index,
+ int formal_parameter_count);
+
+ void Prepare(Isolate* isolate);
+ Handle<Object> GetNext(Isolate* isolate, int level);
+ void Finish(Isolate* isolate);
+
+ int args_length() { return args_length_; }
+
+ private:
+ List<Handle<Object> > materialized_objects_;
+ Handle<FixedArray> previously_materialized_objects_;
+ int prev_materialized_count_;
+ Address stack_frame_id_;
+ List<SlotRef> slot_refs_;
+ int current_slot_;
+ int args_length_;
+ int first_slot_index_;
+
+ static SlotRef ComputeSlotForNextArgument(
+ Translation::Opcode opcode,
+ TranslationIterator* iterator,
+ DeoptimizationInputData* data,
+ JavaScriptFrame* frame);
+
+ Handle<Object> GetPreviouslyMaterialized(Isolate* isolate, int length);
static Address SlotAddress(JavaScriptFrame* frame, int slot_index) {
if (slot_index >= 0) {
}
}
- static SlotRef ComputeSlotForNextArgument(TranslationIterator* iterator,
- DeoptimizationInputData* data,
- JavaScriptFrame* frame);
+ Handle<Object> GetDeferredObject(Isolate* isolate);
+};
- static void ComputeSlotsForArguments(
- Vector<SlotRef>* args_slots,
- TranslationIterator* iterator,
- DeoptimizationInputData* data,
- JavaScriptFrame* frame);
+class MaterializedObjectStore {
+ public:
+ explicit MaterializedObjectStore(Isolate* isolate) : isolate_(isolate) {
+ }
+
+ Handle<FixedArray> Get(Address fp);
+ void Set(Address fp, Handle<FixedArray> materialized_objects);
+ void Remove(Address fp);
+
+ private:
+ Isolate* isolate() { return isolate_; }
+ Handle<FixedArray> GetStackEntries();
+ Handle<FixedArray> EnsureStackEntries(int size);
+
+ int StackIdToIndex(Address fp);
+
+ Isolate* isolate_;
+ List<Address> frame_fps_;
};