From 0a8e5e4b1679f4dd2dd7481b8e595c2eb5f81c21 Mon Sep 17 00:00:00 2001 From: Eurogiciel-BOT Date: Wed, 3 Dec 2014 16:23:51 +0000 Subject: [PATCH 1/1] Upstream version 11.39.258.0 Upstream commit-id 8689eaa25ad11fe474007799ef26ff7b2607e506 Change-Id: I8dfb9ef35bc31d0279aa67ac20a9a8866fd26abf Signed-off-by: Eurogiciel-BOT --- packaging/crosswalk.spec | 2 +- src/v8/src/arm/deoptimizer-arm.cc | 26 +++ src/v8/src/arm64/assembler-arm64-inl.h | 1 + src/v8/src/arm64/assembler-arm64.h | 14 ++ src/v8/src/arm64/deoptimizer-arm64.cc | 38 ++++ src/v8/src/arm64/lithium-arm64.cc | 35 +++ src/v8/src/arm64/lithium-codegen-arm64.cc | 12 + src/v8/src/bootstrapper.cc | 2 + src/v8/src/deoptimizer.cc | 3 + src/v8/src/deoptimizer.h | 27 ++- src/v8/src/elements.h | 2 +- src/v8/src/hydrogen-instructions.h | 120 +++++++++- src/v8/src/hydrogen.cc | 75 +++++- src/v8/src/hydrogen.h | 6 +- src/v8/src/ia32/assembler-ia32.cc | 34 +++ src/v8/src/ia32/assembler-ia32.h | 4 + src/v8/src/ia32/deoptimizer-ia32.cc | 26 +++ src/v8/src/ia32/disasm-ia32.cc | 29 +++ src/v8/src/ia32/lithium-codegen-ia32.cc | 193 +++++++++++++++- src/v8/src/ia32/lithium-ia32.cc | 19 +- src/v8/src/ia32/lithium-ia32.h | 9 +- src/v8/src/mips/assembler-mips-inl.h | 1 + src/v8/src/mips/assembler-mips.h | 1 - src/v8/src/mips/deoptimizer-mips.cc | 39 ++++ src/v8/src/mips/lithium-codegen-mips.cc | 12 + src/v8/src/mips/lithium-mips.cc | 35 +++ src/v8/src/objects.h | 48 +++- src/v8/src/parser.cc | 181 +++++++++++++++ src/v8/src/parser.h | 8 + src/v8/src/preparser.h | 12 + src/v8/src/runtime.cc | 126 ++++++++++ src/v8/src/runtime.h | 20 ++ src/v8/src/simd128.js | 137 +++++++++++ src/v8/src/x64/deoptimizer-x64.cc | 26 +++ src/v8/test/mjsunit/simd/loadstore.js | 253 +++++++++++++++++++++ src/xwalk/DEPS.xwalk | 2 +- src/xwalk/VERSION | 2 +- .../common/xwalk_application_common.gypi | 12 +- src/xwalk/application/tools/tizen/xwalk_backend.cc | 8 +- .../tools/tizen/xwalk_package_installer.cc | 8 +- src/xwalk/application/xwalk_application.gypi | 1 - src/xwalk/build/system.gyp | 17 ++ src/xwalk/packaging/crosswalk.spec | 2 +- src/xwalk/runtime/browser/runtime_ui_delegate.cc | 4 +- src/xwalk/runtime/browser/xwalk_browser_context.cc | 4 + 45 files changed, 1565 insertions(+), 71 deletions(-) create mode 100644 src/v8/test/mjsunit/simd/loadstore.js diff --git a/packaging/crosswalk.spec b/packaging/crosswalk.spec index 28c8490..ee8b27c 100644 --- a/packaging/crosswalk.spec +++ b/packaging/crosswalk.spec @@ -24,7 +24,7 @@ %define _binary_payload w3.gzdio Name: crosswalk -Version: 11.39.256.0 +Version: 11.39.258.0 Release: 0 Summary: Chromium-based app runtime License: (BSD-3-Clause and LGPL-2.1+) diff --git a/src/v8/src/arm/deoptimizer-arm.cc b/src/v8/src/arm/deoptimizer-arm.cc index 567fbbf..ab7ba29 100644 --- a/src/v8/src/arm/deoptimizer-arm.cc +++ b/src/v8/src/arm/deoptimizer-arm.cc @@ -111,6 +111,10 @@ void Deoptimizer::SetPlatformCompiledStubRegisters( } +void Deoptimizer::CopyDoubleRegisters(FrameDescription* output_frame) { +} + + void Deoptimizer::CopySIMD128Registers(FrameDescription* output_frame) { for (int i = 0; i < DwVfpRegister::kMaxNumRegisters; ++i) { double double_value = input_->GetDoubleRegister(i); @@ -361,6 +365,28 @@ void FrameDescription::SetDoubleRegister(unsigned n, double value) { } +simd128_value_t FrameDescription::GetSIMD128Register(unsigned n) const { + DCHECK(n < arraysize(simd128_registers_)); + return simd128_registers_[n]; +} + + +void FrameDescription::SetSIMD128Register(unsigned n, simd128_value_t value) { + DCHECK(n < arraysize(simd128_registers_)); + simd128_registers_[n] = value; +} + + +int FrameDescription::double_registers_offset() { + return OFFSET_OF(FrameDescription, simd128_registers_); +} + + +int FrameDescription::simd128_registers_offset() { + return OFFSET_OF(FrameDescription, simd128_registers_); +} + + #undef __ } } // namespace v8::internal diff --git a/src/v8/src/arm64/assembler-arm64-inl.h b/src/v8/src/arm64/assembler-arm64-inl.h index 5e1bed1..d990eff 100644 --- a/src/v8/src/arm64/assembler-arm64-inl.h +++ b/src/v8/src/arm64/assembler-arm64-inl.h @@ -15,6 +15,7 @@ namespace internal { bool CpuFeatures::SupportsCrankshaft() { return true; } +bool CpuFeatures::SupportsSIMD128InCrankshaft() { return false; } void RelocInfo::apply(intptr_t delta, ICacheFlushMode icache_flush_mode) { diff --git a/src/v8/src/arm64/assembler-arm64.h b/src/v8/src/arm64/assembler-arm64.h index 82b4500..047256a 100644 --- a/src/v8/src/arm64/assembler-arm64.h +++ b/src/v8/src/arm64/assembler-arm64.h @@ -320,6 +320,20 @@ struct FPRegister : public CPURegister { // End of V8 compatibility section ----------------------- }; +struct SIMD128Register { + static const int kMaxNumRegisters = 0; + + static int ToAllocationIndex(SIMD128Register reg) { + UNIMPLEMENTED(); + return -1; + } + + static const char* AllocationIndexToString(int index) { + UNIMPLEMENTED(); + return NULL; + } +}; + STATIC_ASSERT(sizeof(CPURegister) == sizeof(Register)); STATIC_ASSERT(sizeof(CPURegister) == sizeof(FPRegister)); diff --git a/src/v8/src/arm64/deoptimizer-arm64.cc b/src/v8/src/arm64/deoptimizer-arm64.cc index d67dc8f..0589cef 100644 --- a/src/v8/src/arm64/deoptimizer-arm64.cc +++ b/src/v8/src/arm64/deoptimizer-arm64.cc @@ -107,6 +107,9 @@ void Deoptimizer::CopyDoubleRegisters(FrameDescription* output_frame) { } +void Deoptimizer::CopySIMD128Registers(FrameDescription* output_frame) { +} + #define __ masm()-> @@ -351,6 +354,41 @@ void FrameDescription::SetCallerConstantPool(unsigned offset, intptr_t value) { } +double FrameDescription::GetDoubleRegister(unsigned n) const { + DCHECK(n < arraysize(double_registers_)); + return double_registers_[n]; +} + + +void FrameDescription::SetDoubleRegister(unsigned n, double value) { + DCHECK(n < arraysize(double_registers_)); + double_registers_[n] = value; +} + + +simd128_value_t FrameDescription::GetSIMD128Register(unsigned n) const { + UNREACHABLE(); + simd128_value_t value; + return value; +} + + +void FrameDescription::SetSIMD128Register(unsigned n, simd128_value_t value) { + UNREACHABLE(); +} + + +int FrameDescription::double_registers_offset() { + return OFFSET_OF(FrameDescription, double_registers_); +} + + +int FrameDescription::simd128_registers_offset() { + UNREACHABLE(); + return -1; +} + + #undef __ } } // namespace v8::internal diff --git a/src/v8/src/arm64/lithium-arm64.cc b/src/v8/src/arm64/lithium-arm64.cc index 502b046..80857b1 100644 --- a/src/v8/src/arm64/lithium-arm64.cc +++ b/src/v8/src/arm64/lithium-arm64.cc @@ -2752,4 +2752,39 @@ LInstruction* LChunkBuilder::DoAllocateBlockContext( } +LInstruction* LChunkBuilder::DoNullarySIMDOperation( + HNullarySIMDOperation* instr) { + UNIMPLEMENTED(); + return NULL; +} + + +LInstruction* LChunkBuilder::DoUnarySIMDOperation( + HUnarySIMDOperation* instr) { + UNIMPLEMENTED(); + return NULL; +} + + +LInstruction* LChunkBuilder::DoBinarySIMDOperation( + HBinarySIMDOperation* instr) { + UNIMPLEMENTED(); + return NULL; +} + + +LInstruction* LChunkBuilder::DoTernarySIMDOperation( + HTernarySIMDOperation* instr) { + UNIMPLEMENTED(); + return NULL; +} + + +LInstruction* LChunkBuilder::DoQuarternarySIMDOperation( + HQuarternarySIMDOperation* instr) { + UNIMPLEMENTED(); + return NULL; +} + + } } // namespace v8::internal diff --git a/src/v8/src/arm64/lithium-codegen-arm64.cc b/src/v8/src/arm64/lithium-codegen-arm64.cc index 2998642..82ec3a2 100644 --- a/src/v8/src/arm64/lithium-codegen-arm64.cc +++ b/src/v8/src/arm64/lithium-codegen-arm64.cc @@ -3497,8 +3497,14 @@ void LCodeGen::DoLoadKeyedExternal(LLoadKeyedExternal* instr) { break; case FLOAT32_ELEMENTS: case FLOAT64_ELEMENTS: + case INT32x4_ELEMENTS: + case FLOAT32x4_ELEMENTS: + case FLOAT64x2_ELEMENTS: case EXTERNAL_FLOAT32_ELEMENTS: case EXTERNAL_FLOAT64_ELEMENTS: + case EXTERNAL_INT32x4_ELEMENTS: + case EXTERNAL_FLOAT32x4_ELEMENTS: + case EXTERNAL_FLOAT64x2_ELEMENTS: case FAST_HOLEY_DOUBLE_ELEMENTS: case FAST_HOLEY_ELEMENTS: case FAST_HOLEY_SMI_ELEMENTS: @@ -5216,8 +5222,14 @@ void LCodeGen::DoStoreKeyedExternal(LStoreKeyedExternal* instr) { break; case FLOAT32_ELEMENTS: case FLOAT64_ELEMENTS: + case INT32x4_ELEMENTS: + case FLOAT32x4_ELEMENTS: + case FLOAT64x2_ELEMENTS: case EXTERNAL_FLOAT32_ELEMENTS: case EXTERNAL_FLOAT64_ELEMENTS: + case EXTERNAL_INT32x4_ELEMENTS: + case EXTERNAL_FLOAT32x4_ELEMENTS: + case EXTERNAL_FLOAT64x2_ELEMENTS: case FAST_DOUBLE_ELEMENTS: case FAST_ELEMENTS: case FAST_SMI_ELEMENTS: diff --git a/src/v8/src/bootstrapper.cc b/src/v8/src/bootstrapper.cc index 07502c0..e61ab05 100644 --- a/src/v8/src/bootstrapper.cc +++ b/src/v8/src/bootstrapper.cc @@ -2262,6 +2262,8 @@ void Genesis::InstallExperimentalSIMDBuiltinFunctionIds() { InstallBuiltinFunctionId(holder, #fun_name, id); \ } SIMD_ARRAY_OPERATIONS(INSTALL_BUILTIN_ID) + TYPED_ARRAYS_SIMD_LOAD_OPERATIONS(INSTALL_BUILTIN_ID) + TYPED_ARRAYS_SIMD_STORE_OPERATIONS(INSTALL_BUILTIN_ID) #define INSTALL_SIMD_NULLARY_FUNCTION_ID(p1, p2, p3, p4) \ INSTALL_BUILTIN_ID(p1, p2, p3) SIMD_NULLARY_OPERATIONS(INSTALL_SIMD_NULLARY_FUNCTION_ID) diff --git a/src/v8/src/deoptimizer.cc b/src/v8/src/deoptimizer.cc index 14b1bab..b704186 100644 --- a/src/v8/src/deoptimizer.cc +++ b/src/v8/src/deoptimizer.cc @@ -1772,6 +1772,9 @@ void Deoptimizer::DoComputeCompiledStubFrame(TranslationIterator* iterator, } // Copy the double registers from the input into the output frame. + CopyDoubleRegisters(output_frame); + + // Copy the simd128 registers from the input into the output frame. CopySIMD128Registers(output_frame); // Fill registers containing handler and number of parameters. diff --git a/src/v8/src/deoptimizer.h b/src/v8/src/deoptimizer.h index 2056440..5baf67a 100644 --- a/src/v8/src/deoptimizer.h +++ b/src/v8/src/deoptimizer.h @@ -415,6 +415,10 @@ class Deoptimizer : public Malloced { void SetPlatformCompiledStubRegisters(FrameDescription* output_frame, CodeStubDescriptor* 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); @@ -542,7 +546,7 @@ class FrameDescription { // This convoluted DCHECK is needed to work around a gcc problem that // improperly detects an array bounds overflow in optimized debug builds // when using a plain DCHECK. - if (n >= arraysize(registers_)) { + if (n >= arraysize(registers_) { DCHECK(false); return 0; } @@ -552,10 +556,7 @@ class FrameDescription { double GetDoubleRegister(unsigned n) const; - simd128_value_t GetSIMD128Register(unsigned n) const { - DCHECK(n < arraysize(simd128_registers_)); - return simd128_registers_[n]; - } + simd128_value_t GetSIMD128Register(unsigned n) const; void SetRegister(unsigned n, intptr_t value) { DCHECK(n < arraysize(registers_)); @@ -564,10 +565,7 @@ class FrameDescription { void SetDoubleRegister(unsigned n, double value); - void SetSIMD128Register(unsigned n, simd128_value_t value) { - DCHECK(n < arraysize(simd128_registers_)); - simd128_registers_[n] = value; - } + void SetSIMD128Register(unsigned n, simd128_value_t value); intptr_t GetTop() const { return top_; } void SetTop(intptr_t top) { top_ = top; } @@ -610,9 +608,9 @@ class FrameDescription { return OFFSET_OF(FrameDescription, registers_); } - static int simd128_registers_offset() { - return OFFSET_OF(FrameDescription, simd128_registers_); - } + static int double_registers_offset(); + + static int simd128_registers_offset(); static int frame_size_offset() { return OFFSET_OF(FrameDescription, frame_size_); @@ -643,7 +641,12 @@ class FrameDescription { uintptr_t frame_size_; // Number of bytes. JSFunction* function_; intptr_t registers_[Register::kNumRegisters]; +#if V8_TARGET_ARCH_IA32 || V8_TARGET_ARCH_X64 || V8_TARGET_ARCH_ARM + // For these architectures, the simd128 registers cover the double registers. simd128_value_t simd128_registers_[SIMD128Register::kMaxNumRegisters]; +#else + double double_registers_[DoubleRegister::kMaxNumRegisters]; +#endif intptr_t top_; intptr_t pc_; intptr_t fp_; diff --git a/src/v8/src/elements.h b/src/v8/src/elements.h index d0bddf9..88a8201 100644 --- a/src/v8/src/elements.h +++ b/src/v8/src/elements.h @@ -181,7 +181,7 @@ class ElementsAccessor { // Returns a shared ElementsAccessor for the specified ElementsKind. static ElementsAccessor* ForKind(ElementsKind elements_kind) { - DCHECK(elements_kind < kElementsKindCount); + DCHECK(static_cast(elements_kind) < kElementsKindCount); return elements_accessors_[elements_kind]; } diff --git a/src/v8/src/hydrogen-instructions.h b/src/v8/src/hydrogen-instructions.h index 36fce89..200cdee 100644 --- a/src/v8/src/hydrogen-instructions.h +++ b/src/v8/src/hydrogen-instructions.h @@ -1017,6 +1017,19 @@ OStream& operator<<(OStream& os, const ChangesOf& v); return new(zone) I(p1, p2, p3, p4, p5, p6); \ } +#define DECLARE_INSTRUCTION_FACTORY_P7(I, P1, P2, P3, P4, P5, P6, P7) \ + static I* New(Zone* zone, \ + HValue* context, \ + P1 p1, \ + P2 p2, \ + P3 p3, \ + P4 p4, \ + P5 p5, \ + P6 p6, \ + P7 p7) { \ + return new(zone) I(p1, p2, p3, p4, p5, p6, p7); \ + } + #define DECLARE_INSTRUCTION_WITH_CONTEXT_FACTORY_P0(I) \ static I* New(Zone* zone, HValue* context) { \ return new(zone) I(context); \ @@ -4047,6 +4060,8 @@ class HBoundsCheckBaseIndexInformation; class HBoundsCheck FINAL : public HTemplateInstruction<2> { public: DECLARE_INSTRUCTION_FACTORY_P2(HBoundsCheck, HValue*, HValue*); + DECLARE_INSTRUCTION_FACTORY_P4(HBoundsCheck, HValue*, HValue*, + BuiltinFunctionId, ElementsKind); bool skip_check() const { return skip_check_; } void set_skip_check() { skip_check_ = true; } @@ -4085,6 +4100,8 @@ class HBoundsCheck FINAL : public HTemplateInstruction<2> { HValue* length() const { return OperandAt(1); } bool allow_equality() const { return allow_equality_; } void set_allow_equality(bool v) { allow_equality_ = v; } + BuiltinFunctionId op() const { return op_; } + ElementsKind element_kind() const { return element_kind_; } virtual int RedefinedOperandIndex() OVERRIDE { return 0; } virtual bool IsPurelyInformativeDefinition() OVERRIDE { @@ -4104,16 +4121,21 @@ class HBoundsCheck FINAL : public HTemplateInstruction<2> { int offset_; int scale_; bool allow_equality_; + BuiltinFunctionId op_; + ElementsKind element_kind_; private: // Normally HBoundsCheck should be created using the // HGraphBuilder::AddBoundsCheck() helper. // However when building stubs, where we know that the arguments are Int32, // it makes sense to invoke this constructor directly. - HBoundsCheck(HValue* index, HValue* length) + HBoundsCheck(HValue* index, HValue* length, + BuiltinFunctionId op = kNumberOfBuiltinFunction, + ElementsKind element_kind = EXTERNAL_INT8_ELEMENTS) : skip_check_(false), base_(NULL), offset_(0), scale_(0), - allow_equality_(false) { + allow_equality_(false), op_(op), + element_kind_(element_kind) { SetOperandAt(0, index); SetOperandAt(1, length); SetFlag(kFlexibleRepresentation); @@ -6603,6 +6625,9 @@ class HLoadKeyed FINAL ElementsKind, LoadKeyedHoleMode); DECLARE_INSTRUCTION_FACTORY_P6(HLoadKeyed, HValue*, HValue*, HValue*, ElementsKind, LoadKeyedHoleMode, int); + DECLARE_INSTRUCTION_FACTORY_P7(HLoadKeyed, HValue*, HValue*, HValue*, + ElementsKind, LoadKeyedHoleMode, int, + BuiltinFunctionId); bool is_external() const { return IsExternalArrayElementsKind(elements_kind()); @@ -6622,6 +6647,7 @@ class HLoadKeyed FINAL bool HasDependency() const { return OperandAt(0) != OperandAt(2); } uint32_t base_offset() const { return BaseOffsetField::decode(bit_field_); } bool TryIncreaseBaseOffset(uint32_t increase_by_value); + BuiltinFunctionId op() {return op_;} HValue* GetKey() { return key(); } void SetKey(HValue* key) { SetOperandAt(1, key); } bool IsDehoisted() const { return IsDehoistedField::decode(bit_field_); } @@ -6681,8 +6707,9 @@ class HLoadKeyed FINAL HValue* dependency, ElementsKind elements_kind, LoadKeyedHoleMode mode = NEVER_RETURN_HOLE, - int offset = kDefaultKeyedHeaderOffsetSentinel) - : bit_field_(0) { + int offset = kDefaultKeyedHeaderOffsetSentinel, + BuiltinFunctionId op = kNumberOfBuiltinFunction) + : bit_field_(0), op_(op) { offset = offset == kDefaultKeyedHeaderOffsetSentinel ? GetDefaultHeaderSizeForElementsKind(elements_kind) : offset; @@ -6720,7 +6747,30 @@ class HLoadKeyed FINAL SetDependsOnFlag(kDoubleArrayElements); } } else { - if (elements_kind == EXTERNAL_FLOAT32_ELEMENTS || + if (op_ == kFloat32ArrayGetFloat32x4XYZW || + op_ == kFloat32ArrayGetFloat32x4X || + op_ == kFloat32ArrayGetFloat32x4XY || + op_ == kFloat32ArrayGetFloat32x4XYZ || + op_ == kInt8ArrayGetFloat32x4XYZW || + op_ == kInt8ArrayGetFloat32x4X || + op_ == kInt8ArrayGetFloat32x4XY || + op_ == kInt8ArrayGetFloat32x4XYZ) { + set_representation(Representation::Float32x4()); + } else if (op_ == kFloat64ArrayGetFloat64x2XY || + op_ == kFloat64ArrayGetFloat64x2X || + op_ == kInt8ArrayGetFloat64x2XY || + op_ == kInt8ArrayGetFloat64x2X) { + set_representation(Representation::Float64x2()); + } else if (op_ == kInt32ArrayGetInt32x4XYZW || + op_ == kInt32ArrayGetInt32x4X || + op_ == kInt32ArrayGetInt32x4XY || + op_ == kInt32ArrayGetInt32x4XYZ || + op_ == kInt8ArrayGetInt32x4XYZW || + op_ == kInt8ArrayGetInt32x4X || + op_ == kInt8ArrayGetInt32x4XY || + op_ == kInt8ArrayGetInt32x4XYZ) { + set_representation(Representation::Int32x4()); + } else if (elements_kind == EXTERNAL_FLOAT32_ELEMENTS || elements_kind == EXTERNAL_FLOAT64_ELEMENTS || elements_kind == FLOAT32_ELEMENTS || elements_kind == FLOAT64_ELEMENTS) { @@ -6785,6 +6835,7 @@ class HLoadKeyed FINAL public BitField {}; // NOLINT uint32_t bit_field_; + BuiltinFunctionId op_; }; @@ -7036,6 +7087,9 @@ class HStoreKeyed FINAL ElementsKind, StoreFieldOrKeyedMode); DECLARE_INSTRUCTION_FACTORY_P6(HStoreKeyed, HValue*, HValue*, HValue*, ElementsKind, StoreFieldOrKeyedMode, int); + DECLARE_INSTRUCTION_FACTORY_P7(HStoreKeyed, HValue*, HValue*, HValue*, + ElementsKind, StoreFieldOrKeyedMode, int, + BuiltinFunctionId); virtual Representation RequiredInputRepresentation(int index) OVERRIDE { // kind_fast: tagged[int32] = tagged @@ -7052,6 +7106,30 @@ class HStoreKeyed FINAL } DCHECK_EQ(index, 2); + if (op_ == kFloat32ArraySetFloat32x4XYZW || + op_ == kFloat32ArraySetFloat32x4X || + op_ == kFloat32ArraySetFloat32x4XY || + op_ == kFloat32ArraySetFloat32x4XYZ || + op_ == kInt8ArraySetFloat32x4XYZW || + op_ == kInt8ArraySetFloat32x4X || + op_ == kInt8ArraySetFloat32x4XY || + op_ == kInt8ArraySetFloat32x4XYZ) { + return Representation::Float32x4(); + } else if (op_ == kFloat64ArraySetFloat64x2XY || + op_ == kFloat64ArraySetFloat64x2X || + op_ == kInt8ArraySetFloat64x2XY || + op_ == kInt8ArraySetFloat64x2X) { + return Representation::Float64x2(); + } else if (op_ == kInt32ArraySetInt32x4XYZW || + op_ == kInt32ArraySetInt32x4X || + op_ == kInt32ArraySetInt32x4XY || + op_ == kInt32ArraySetInt32x4XYZ || + op_ == kInt8ArraySetInt32x4XYZW || + op_ == kInt8ArraySetInt32x4X || + op_ == kInt8ArraySetInt32x4XY || + op_ == kInt8ArraySetInt32x4XYZ) { + return Representation::Int32x4(); + } return RequiredValueRepresentation(elements_kind_, store_mode_); } @@ -7106,12 +7184,37 @@ class HStoreKeyed FINAL if (IsUninitialized()) { return Representation::None(); } + if (op_ == kFloat32ArraySetFloat32x4XYZW || + op_ == kFloat32ArraySetFloat32x4X || + op_ == kFloat32ArraySetFloat32x4XY || + op_ == kFloat32ArraySetFloat32x4XYZ || + op_ == kInt8ArraySetFloat32x4XYZW || + op_ == kInt8ArraySetFloat32x4X || + op_ == kInt8ArraySetFloat32x4XY || + op_ == kInt8ArraySetFloat32x4XYZ) { + return Representation::Float32x4(); + } else if (op_ == kFloat64ArraySetFloat64x2XY || + op_ == kFloat64ArraySetFloat64x2X || + op_ == kInt8ArraySetFloat64x2XY || + op_ == kInt8ArraySetFloat64x2X) { + return Representation::Float64x2(); + } else if (op_ == kInt32ArraySetInt32x4XYZW || + op_ == kInt32ArraySetInt32x4X || + op_ == kInt32ArraySetInt32x4XY || + op_ == kInt32ArraySetInt32x4XYZ || + op_ == kInt8ArraySetInt32x4XYZW || + op_ == kInt8ArraySetInt32x4X || + op_ == kInt8ArraySetInt32x4XY || + op_ == kInt8ArraySetInt32x4XYZ) { + return Representation::Int32x4(); + } Representation r = RequiredValueRepresentation(elements_kind_, store_mode_); // For fast object elements kinds, don't assume anything. if (r.IsTagged()) return Representation::None(); return r; } + BuiltinFunctionId op() const { return op_; } HValue* elements() const { return OperandAt(0); } HValue* key() const { return OperandAt(1); } HValue* value() const { return OperandAt(2); } @@ -7167,7 +7270,8 @@ class HStoreKeyed FINAL HStoreKeyed(HValue* obj, HValue* key, HValue* val, ElementsKind elements_kind, StoreFieldOrKeyedMode store_mode = INITIALIZING_STORE, - int offset = kDefaultKeyedHeaderOffsetSentinel) + int offset = kDefaultKeyedHeaderOffsetSentinel, + BuiltinFunctionId op = kNumberOfBuiltinFunction) : elements_kind_(elements_kind), base_offset_(offset == kDefaultKeyedHeaderOffsetSentinel ? GetDefaultHeaderSizeForElementsKind(elements_kind) @@ -7175,7 +7279,8 @@ class HStoreKeyed FINAL is_dehoisted_(false), is_uninitialized_(false), store_mode_(store_mode), - dominator_(NULL) { + dominator_(NULL), + op_(op) { SetOperandAt(0, obj); SetOperandAt(1, key); SetOperandAt(2, val); @@ -7213,6 +7318,7 @@ class HStoreKeyed FINAL bool is_uninitialized_ : 1; StoreFieldOrKeyedMode store_mode_: 1; HValue* dominator_; + BuiltinFunctionId op_; }; diff --git a/src/v8/src/hydrogen.cc b/src/v8/src/hydrogen.cc index 890a976..cde6d1f 100644 --- a/src/v8/src/hydrogen.cc +++ b/src/v8/src/hydrogen.cc @@ -2403,7 +2403,8 @@ HInstruction* HGraphBuilder::BuildUncheckedMonomorphicElementAccess( ElementsKind elements_kind, PropertyAccessType access_type, LoadKeyedHoleMode load_mode, - KeyedAccessStoreMode store_mode) { + KeyedAccessStoreMode store_mode, + BuiltinFunctionId op) { DCHECK((!IsExternalArrayElementsKind(elements_kind) && !IsFixedTypedArrayElementsKind(elements_kind)) || !is_js_array); @@ -2464,10 +2465,10 @@ HInstruction* HGraphBuilder::BuildUncheckedMonomorphicElementAccess( return result; } else { DCHECK(store_mode == STANDARD_STORE); - checked_key = Add(key, length); + checked_key = Add(key, length, op, elements_kind); return AddElementAccess( backing_store, checked_key, val, - checked_object, elements_kind, access_type); + checked_object, elements_kind, access_type, NEVER_RETURN_HOLE, op); } } DCHECK(fast_smi_only_elements || @@ -2507,7 +2508,7 @@ HInstruction* HGraphBuilder::BuildUncheckedMonomorphicElementAccess( } } return AddElementAccess(elements, checked_key, val, checked_object, - elements_kind, access_type, load_mode); + elements_kind, access_type, load_mode, op); } @@ -2675,7 +2676,8 @@ HInstruction* HGraphBuilder::AddElementAccess( HValue* dependency, ElementsKind elements_kind, PropertyAccessType access_type, - LoadKeyedHoleMode load_mode) { + LoadKeyedHoleMode load_mode, + BuiltinFunctionId op) { if (access_type == STORE) { DCHECK(val != NULL); if (elements_kind == EXTERNAL_UINT8_CLAMPED_ELEMENTS || @@ -2683,13 +2685,15 @@ HInstruction* HGraphBuilder::AddElementAccess( val = Add(val); } return Add(elements, checked_key, val, elements_kind, - STORE_TO_INITIALIZED_ENTRY); + STORE_TO_INITIALIZED_ENTRY, + kDefaultKeyedHeaderOffsetSentinel, op); } DCHECK(access_type == LOAD); DCHECK(val == NULL); HLoadKeyed* load = Add( - elements, checked_key, dependency, elements_kind, load_mode); + elements, checked_key, dependency, elements_kind, load_mode, + kDefaultKeyedHeaderOffsetSentinel, op); if (FLAG_opt_safe_uint32_operations && (elements_kind == EXTERNAL_UINT32_ELEMENTS || elements_kind == UINT32_ELEMENTS)) { @@ -8873,6 +8877,63 @@ SIMD_QUARTERNARY_OPERATIONS(SIMD_QUARTERNARY_OPERATION_CASE_ITEM) } } break; +#define TYPED_ARRAY_SIMD_LOAD_OPERATION_CASE_ITEM(p1, p2, name) \ + case k##name: +TYPED_ARRAYS_SIMD_LOAD_OPERATIONS(TYPED_ARRAY_SIMD_LOAD_OPERATION_CASE_ITEM) +#undef TYPED_ARRAY_SIMD_LOAD_OPERATION_CASE_ITEM + if (receiver_map.is_null()) return false; + if (CpuFeatures::SupportsSIMD128InCrankshaft() && argument_count == 2) { +#if V8_TARGET_ARCH_X64 + // TODO(nhu): support x64. + return false; +#else + HValue* key = Pop(); + HValue* tarray = Pop(); + DCHECK(tarray == receiver); + Drop(1); // Drop function. + HInstruction* instr = BuildUncheckedMonomorphicElementAccess( + tarray, key, NULL, + receiver_map->instance_type() == JS_ARRAY_TYPE, + receiver_map->elements_kind(), + LOAD, // is_store. + NEVER_RETURN_HOLE, // load_mode. + STANDARD_STORE, + id); + ast_context()->ReturnValue(instr); + return true; +#endif + } + break; +#define TYPED_ARRAY_SIMD_STORE_OPERATION_CASE_ITEM(p1, p2, name) \ + case k##name: +TYPED_ARRAYS_SIMD_STORE_OPERATIONS(TYPED_ARRAY_SIMD_STORE_OPERATION_CASE_ITEM) +#undef TYPED_ARRAY_SIMD_STORE_OPERATION_CASE_ITEM + if (receiver_map.is_null()) return false; + if (CpuFeatures::SupportsSIMD128InCrankshaft() && argument_count == 3) { +#if V8_TARGET_ARCH_X64 + // TODO(nhu): support x64. + return false; +#else + HValue* value = Pop(); + HValue* key = Pop(); + HValue* tarray = Pop(); + Drop(1); // Drop function. + DCHECK(tarray == receiver); + BuildUncheckedMonomorphicElementAccess( + tarray, key, value, + receiver_map->instance_type() == JS_ARRAY_TYPE, + receiver_map->elements_kind(), + STORE, // is_store. + NEVER_RETURN_HOLE, // load_mode. + STANDARD_STORE, + id); + Push(value); + Add(expr->id(), REMOVABLE_SIMULATE); + ast_context()->ReturnValue(Pop()); + return true; +#endif + } + break; case kFloat32x4ArrayGetAt: case kFloat64x2ArrayGetAt: case kInt32x4ArrayGetAt: diff --git a/src/v8/src/hydrogen.h b/src/v8/src/hydrogen.h index 4dfaa4e..6d6bc8a 100644 --- a/src/v8/src/hydrogen.h +++ b/src/v8/src/hydrogen.h @@ -1422,7 +1422,8 @@ class HGraphBuilder { ElementsKind elements_kind, PropertyAccessType access_type, LoadKeyedHoleMode load_mode, - KeyedAccessStoreMode store_mode); + KeyedAccessStoreMode store_mode, + BuiltinFunctionId id = kNumberOfBuiltinFunction); HInstruction* AddElementAccess( HValue* elements, @@ -1431,7 +1432,8 @@ class HGraphBuilder { HValue* dependency, ElementsKind elements_kind, PropertyAccessType access_type, - LoadKeyedHoleMode load_mode = NEVER_RETURN_HOLE); + LoadKeyedHoleMode load_mode = NEVER_RETURN_HOLE, + BuiltinFunctionId id = kNumberOfBuiltinFunction); HInstruction* AddLoadStringInstanceType(HValue* string); HInstruction* AddLoadStringLength(HValue* string); diff --git a/src/v8/src/ia32/assembler-ia32.cc b/src/v8/src/ia32/assembler-ia32.cc index da69ff4..ce59f92 100644 --- a/src/v8/src/ia32/assembler-ia32.cc +++ b/src/v8/src/ia32/assembler-ia32.cc @@ -2308,6 +2308,22 @@ void Assembler::movaps(XMMRegister dst, XMMRegister src) { } +void Assembler::movlhps(XMMRegister dst, XMMRegister src) { + EnsureSpace ensure_space(this); + EMIT(0x0F); + EMIT(0x16); + emit_sse_operand(dst, src); +} + + +void Assembler::movhlps(XMMRegister dst, XMMRegister src) { + EnsureSpace ensure_space(this); + EMIT(0x0F); + EMIT(0x12); + emit_sse_operand(dst, src); +} + + void Assembler::movups(XMMRegister dst, const Operand& src) { EnsureSpace ensure_space(this); EMIT(0x0F); @@ -2448,6 +2464,24 @@ void Assembler::movss(XMMRegister dst, const Operand& src) { } +void Assembler::movq(const Operand& dst, XMMRegister src ) { + EnsureSpace ensure_space(this); + EMIT(0x66); + EMIT(0x0F); + EMIT(0xD6); // store + emit_sse_operand(src, dst); +} + + +void Assembler::movq(XMMRegister dst, const Operand& src) { + EnsureSpace ensure_space(this); + EMIT(0xF3); + EMIT(0x0F); + EMIT(0x7E); // load + emit_sse_operand(dst, src); +} + + void Assembler::movd(XMMRegister dst, const Operand& src) { EnsureSpace ensure_space(this); EMIT(0x66); diff --git a/src/v8/src/ia32/assembler-ia32.h b/src/v8/src/ia32/assembler-ia32.h index c9e06c4..5fab96b 100644 --- a/src/v8/src/ia32/assembler-ia32.h +++ b/src/v8/src/ia32/assembler-ia32.h @@ -925,6 +925,8 @@ class Assembler : public AssemblerBase { // SSE instructions void movaps(XMMRegister dst, XMMRegister src); + void movlhps(XMMRegister dst, XMMRegister src); + void movhlps(XMMRegister dst, XMMRegister src); void movups(XMMRegister dst, const Operand& src); void movups(const Operand& dst, XMMRegister src); void shufps(XMMRegister dst, XMMRegister src, byte imm8); @@ -1078,6 +1080,8 @@ class Assembler : public AssemblerBase { void movss(XMMRegister dst, const Operand& src); void movss(const Operand& dst, XMMRegister src); void movss(XMMRegister dst, XMMRegister src) { movss(dst, Operand(src)); } + void movq(XMMRegister dst, const Operand& src); + void movq(const Operand& dst, XMMRegister src); void extractps(Register dst, XMMRegister src, byte imm8); void pand(XMMRegister dst, XMMRegister src); diff --git a/src/v8/src/ia32/deoptimizer-ia32.cc b/src/v8/src/ia32/deoptimizer-ia32.cc index 2e372e4..4b2d04e 100644 --- a/src/v8/src/ia32/deoptimizer-ia32.cc +++ b/src/v8/src/ia32/deoptimizer-ia32.cc @@ -204,6 +204,10 @@ void Deoptimizer::SetPlatformCompiledStubRegisters( } +void Deoptimizer::CopyDoubleRegisters(FrameDescription* output_frame) { +} + + void Deoptimizer::CopySIMD128Registers(FrameDescription* output_frame) { for (int i = 0; i < XMMRegister::kMaxNumAllocatableRegisters; ++i) { simd128_value_t xmm_value = input_->GetSIMD128Register(i); @@ -437,6 +441,28 @@ void FrameDescription::SetDoubleRegister(unsigned n, double value) { } +simd128_value_t FrameDescription::GetSIMD128Register(unsigned n) const { + DCHECK(n < arraysize(simd128_registers_)); + return simd128_registers_[n]; +} + + +void FrameDescription::SetSIMD128Register(unsigned n, simd128_value_t value) { + DCHECK(n < arraysize(simd128_registers_)); + simd128_registers_[n] = value; +} + + +int FrameDescription::double_registers_offset() { + return OFFSET_OF(FrameDescription, simd128_registers_); +} + + +int FrameDescription::simd128_registers_offset() { + return OFFSET_OF(FrameDescription, simd128_registers_); +} + + #undef __ diff --git a/src/v8/src/ia32/disasm-ia32.cc b/src/v8/src/ia32/disasm-ia32.cc index e36b390..a93e57a 100644 --- a/src/v8/src/ia32/disasm-ia32.cc +++ b/src/v8/src/ia32/disasm-ia32.cc @@ -1047,6 +1047,22 @@ int DisassemblerIA32::InstructionDecode(v8::internal::Vector out_buffer, NameOfXMMRegister(regop), NameOfXMMRegister(rm)); data++; + } else if (f0byte == 0x12) { + data += 2; + int mod, regop, rm; + get_modrm(*data, &mod, ®op, &rm); + AppendToBuffer("movhlps %s,%s", + NameOfXMMRegister(regop), + NameOfXMMRegister(rm)); + data++; + } else if (f0byte == 0x16) { + data += 2; + int mod, regop, rm; + get_modrm(*data, &mod, ®op, &rm); + AppendToBuffer("movlhps %s,%s", + NameOfXMMRegister(regop), + NameOfXMMRegister(rm)); + data++; } else if (f0byte == 0x10) { data += 2; int mod, regop, rm; @@ -1467,6 +1483,13 @@ int DisassemblerIA32::InstructionDecode(v8::internal::Vector out_buffer, AppendToBuffer("punpackldq %s,", NameOfXMMRegister(regop)); data += PrintRightXMMOperand(data); + } else if (*data == 0xD6) { + AppendToBuffer("movq "); + data += 3; + int mod, regop, rm; + get_modrm(*data, &mod, ®op, &rm); + data += PrintRightXMMOperand(data); + AppendToBuffer(",%s", NameOfXMMRegister(regop)); } else if (*data == 0xF4) { data++; int mod, regop, rm; @@ -1824,6 +1847,12 @@ int DisassemblerIA32::InstructionDecode(v8::internal::Vector out_buffer, get_modrm(*data, &mod, ®op, &rm); data += PrintRightXMMOperand(data); AppendToBuffer(",%s", NameOfXMMRegister(regop)); + } else if (b2 == 0x7E) { + data += 3; + int mod, regop, rm; + get_modrm(*data, &mod, ®op, &rm); + AppendToBuffer("movq %s,", NameOfXMMRegister(regop)); + data += PrintRightXMMOperand(data); } else { UnimplementedInstruction(); } diff --git a/src/v8/src/ia32/lithium-codegen-ia32.cc b/src/v8/src/ia32/lithium-codegen-ia32.cc index ffebf49..f56a027 100644 --- a/src/v8/src/ia32/lithium-codegen-ia32.cc +++ b/src/v8/src/ia32/lithium-codegen-ia32.cc @@ -19,6 +19,102 @@ namespace v8 { namespace internal { +inline bool IsSIMD128LoadStoreOp(BuiltinFunctionId op) { + return (op == kFloat32ArrayGetFloat32x4XYZW || + op == kFloat32ArrayGetFloat32x4X || + op == kFloat32ArrayGetFloat32x4XY || + op == kFloat32ArrayGetFloat32x4XYZ || + op == kFloat64ArrayGetFloat64x2XY || + op == kFloat64ArrayGetFloat64x2X || + op == kInt32ArrayGetInt32x4XYZW || + op == kInt32ArrayGetInt32x4X || + op == kInt32ArrayGetInt32x4XY || + op == kInt32ArrayGetInt32x4XYZ || + op == kInt8ArrayGetFloat32x4XYZW || + op == kInt8ArrayGetFloat32x4X || + op == kInt8ArrayGetFloat32x4XY || + op == kInt8ArrayGetFloat32x4XYZ || + op == kInt8ArrayGetFloat64x2XY || + op == kInt8ArrayGetFloat64x2X || + op == kInt8ArrayGetInt32x4XYZW || + op == kInt8ArrayGetInt32x4X || + op == kInt8ArrayGetInt32x4XY || + op == kInt8ArrayGetInt32x4XYZ || + op == kFloat32ArraySetFloat32x4XYZW || + op == kFloat32ArraySetFloat32x4X || + op == kFloat32ArraySetFloat32x4XY || + op == kFloat32ArraySetFloat32x4XYZ || + op == kFloat64ArraySetFloat64x2XY || + op == kFloat64ArraySetFloat64x2X || + op == kInt32ArraySetInt32x4XYZW || + op == kInt32ArraySetInt32x4X || + op == kInt32ArraySetInt32x4XY || + op == kInt32ArraySetInt32x4XYZ || + op == kInt8ArraySetFloat32x4XYZW || + op == kInt8ArraySetFloat32x4X || + op == kInt8ArraySetFloat32x4XY || + op == kInt8ArraySetFloat32x4XYZ || + op == kInt8ArraySetFloat64x2XY || + op == kInt8ArraySetFloat64x2X || + op == kInt8ArraySetInt32x4XYZW || + op == kInt8ArraySetInt32x4X || + op == kInt8ArraySetInt32x4XY || + op == kInt8ArraySetInt32x4XYZ); +} + + +int GetSIMD128LoadStoreBytes(BuiltinFunctionId op) { + if (op == kFloat32ArrayGetFloat32x4XYZW || + op == kFloat64ArrayGetFloat64x2XY || + op == kInt32ArrayGetInt32x4XYZW || + op == kInt8ArrayGetFloat32x4XYZW || + op == kInt8ArrayGetFloat64x2XY || + op == kInt8ArrayGetInt32x4XYZW || + op == kFloat32ArraySetFloat32x4XYZW || + op == kFloat64ArraySetFloat64x2XY || + op == kInt32ArraySetInt32x4XYZW || + op == kInt8ArraySetFloat32x4XYZW || + op == kInt8ArraySetFloat64x2XY || + op == kInt8ArraySetInt32x4XYZW) { + return 16; + } else if (op == kFloat32ArrayGetFloat32x4X || + op == kInt32ArrayGetInt32x4X || + op == kInt8ArrayGetFloat32x4X || + op == kInt8ArrayGetInt32x4X || + op == kFloat32ArraySetFloat32x4X || + op == kInt32ArraySetInt32x4X || + op == kInt8ArraySetFloat32x4X || + op == kInt8ArraySetInt32x4X) { + return 4; + } else if (op == kFloat32ArrayGetFloat32x4XY || + op == kFloat64ArrayGetFloat64x2X || + op == kInt32ArrayGetInt32x4XY || + op == kInt8ArrayGetFloat32x4XY || + op == kInt8ArrayGetFloat64x2X || + op == kInt8ArrayGetInt32x4XY || + op == kFloat32ArraySetFloat32x4XY || + op == kFloat64ArraySetFloat64x2X || + op == kInt32ArraySetInt32x4XY || + op == kInt8ArraySetFloat32x4XY || + op == kInt8ArraySetFloat64x2X || + op == kInt8ArraySetInt32x4XY) { + return 8; + } else if (op == kFloat32ArrayGetFloat32x4XYZ || + op == kInt32ArrayGetInt32x4XYZ || + op == kInt8ArrayGetFloat32x4XYZ || + op == kInt8ArrayGetInt32x4XYZ || + op == kFloat32ArraySetFloat32x4XYZ || + op == kInt32ArraySetInt32x4XYZ || + op == kInt8ArraySetFloat32x4XYZ || + op == kInt8ArraySetInt32x4XYZ) { + return 12; + } else { + UNREACHABLE(); + return -1; + } +} + + // When invoking builtins, we need to record the safepoint in the middle of // the invoke instruction sequence generated by the macro assembler. class SafepointGenerator FINAL : public CallWrapper { @@ -3149,7 +3245,28 @@ void LCodeGen::DoLoadKeyedExternalArray(LLoadKeyed* instr) { instr->hydrogen()->key()->representation(), elements_kind, instr->base_offset())); - if (elements_kind == EXTERNAL_FLOAT32_ELEMENTS || + BuiltinFunctionId op = instr->hydrogen()->op(); + if (IsSIMD128LoadStoreOp(op)) { + if (GetSIMD128LoadStoreBytes(op) == 16) { + __ movups(ToSIMD128Register(instr->result()), operand); + } else if (GetSIMD128LoadStoreBytes(op) == 4) { + __ movss(ToSIMD128Register(instr->result()), operand); + } else if (GetSIMD128LoadStoreBytes(op) == 8) { + __ movq(ToSIMD128Register(instr->result()), operand); + } else if (GetSIMD128LoadStoreBytes(op) == 12) { + XMMRegister result(ToSIMD128Register(instr->result())); + XMMRegister xmm_scratch = double_scratch0(); + __ movq(result, operand); + Operand operand2(BuildFastArrayOperand( + instr->elements(), + key, + instr->hydrogen()->key()->representation(), + elements_kind, + instr->base_offset() + 8)); + __ movss(xmm_scratch, operand2); + __ movlhps(result, xmm_scratch); + } + } else if (elements_kind == EXTERNAL_FLOAT32_ELEMENTS || elements_kind == FLOAT32_ELEMENTS) { XMMRegister result(ToDoubleRegister(instr->result())); __ movss(result, operand); @@ -4203,17 +4320,48 @@ void LCodeGen::DoStoreNamedGeneric(LStoreNamedGeneric* instr) { void LCodeGen::DoBoundsCheck(LBoundsCheck* instr) { Condition cc = instr->hydrogen()->allow_equality() ? above : above_equal; - if (instr->index()->IsConstantOperand()) { - __ cmp(ToOperand(instr->length()), - ToImmediate(LConstantOperand::cast(instr->index()), - instr->hydrogen()->length()->representation())); - cc = CommuteCondition(cc); - } else if (instr->length()->IsConstantOperand()) { - __ cmp(ToOperand(instr->index()), - ToImmediate(LConstantOperand::cast(instr->length()), - instr->hydrogen()->index()->representation())); + BuiltinFunctionId op = instr->hydrogen()->op(); + if (IsSIMD128LoadStoreOp(op)) { + cc = above; + Register index_in_bytes = ToRegister(instr->temp0()); + Register length_in_bytes = ToRegister(instr->temp1()); + if (instr->index()->IsConstantOperand()) + __ mov(index_in_bytes, ToImmediate(LConstantOperand::cast(instr->index()), + instr->hydrogen()->index()->representation())); + else + __ mov(index_in_bytes, ToOperand(instr->index())); + int index_shift_size = + ElementsKindToShiftSize(instr->hydrogen()->element_kind()); + DCHECK(index_shift_size >= 0); + if (index_shift_size > 0) + __ shl(index_in_bytes, index_shift_size); + int bytes = GetSIMD128LoadStoreBytes(op); + __ add(index_in_bytes, Immediate(bytes)); + if (instr->length()->IsConstantOperand()) + __ mov(length_in_bytes, + ToImmediate(LConstantOperand::cast(instr->length()), + instr->hydrogen()->length()->representation())); + else + __ mov(length_in_bytes, ToOperand(instr->length())); + int length_shift_size = + ElementsKindToShiftSize(instr->hydrogen()->element_kind()); + DCHECK(length_shift_size >= 0); + if (length_shift_size > 0) + __ shl(length_in_bytes, length_shift_size); + __ cmp(index_in_bytes, length_in_bytes); } else { - __ cmp(ToRegister(instr->index()), ToOperand(instr->length())); + if (instr->index()->IsConstantOperand()) { + __ cmp(ToOperand(instr->length()), + ToImmediate(LConstantOperand::cast(instr->index()), + instr->hydrogen()->length()->representation())); + cc = CommuteCondition(cc); + } else if (instr->length()->IsConstantOperand()) { + __ cmp(ToOperand(instr->index()), + ToImmediate(LConstantOperand::cast(instr->length()), + instr->hydrogen()->index()->representation())); + } else { + __ cmp(ToRegister(instr->index()), ToOperand(instr->length())); + } } if (FLAG_debug_code && instr->hydrogen()->skip_check()) { Label done; @@ -4242,7 +4390,28 @@ void LCodeGen::DoStoreKeyedExternalArray(LStoreKeyed* instr) { instr->hydrogen()->key()->representation(), elements_kind, instr->base_offset())); - if (elements_kind == EXTERNAL_FLOAT32_ELEMENTS || + BuiltinFunctionId op = instr->hydrogen()->op(); + if (IsSIMD128LoadStoreOp(op)) { + if (GetSIMD128LoadStoreBytes(op) == 16) { + __ movups(operand, ToSIMD128Register(instr->value())); + } else if (GetSIMD128LoadStoreBytes(op) == 4) { + __ movss(operand, ToSIMD128Register(instr->value())); + } else if (GetSIMD128LoadStoreBytes(op) == 8) { + __ movq(operand, ToSIMD128Register(instr->value())); + } else if (GetSIMD128LoadStoreBytes(op) == 12) { + XMMRegister value(ToSIMD128Register(instr->value())); + XMMRegister xmm_scratch = double_scratch0(); + __ movq(operand, value); + Operand operand2(BuildFastArrayOperand( + instr->elements(), + key, + instr->hydrogen()->key()->representation(), + elements_kind, + instr->base_offset() + 8)); + __ movhlps(xmm_scratch, value); + __ movss(operand2, xmm_scratch); + } + } else if (elements_kind == EXTERNAL_FLOAT32_ELEMENTS || elements_kind == FLOAT32_ELEMENTS) { XMMRegister xmm_scratch = double_scratch0(); __ cvtsd2ss(xmm_scratch, ToDoubleRegister(instr->value())); diff --git a/src/v8/src/ia32/lithium-ia32.cc b/src/v8/src/ia32/lithium-ia32.cc index 7422da0..dd6e854 100644 --- a/src/v8/src/ia32/lithium-ia32.cc +++ b/src/v8/src/ia32/lithium-ia32.cc @@ -1877,7 +1877,9 @@ LInstruction* LChunkBuilder::DoBoundsCheck(HBoundsCheck* instr) { LOperand* length = !index->IsConstantOperand() ? UseOrConstantAtStart(instr->length()) : UseAtStart(instr->length()); - LInstruction* result = new(zone()) LBoundsCheck(index, length); + LOperand* temp0 = TempRegister(); + LOperand* temp1 = TempRegister(); + LInstruction* result = new(zone()) LBoundsCheck(index, length, temp0, temp1); if (!FLAG_debug_code || !instr->skip_check()) { result = AssignEnvironment(result); } @@ -2301,15 +2303,26 @@ LInstruction* LChunkBuilder::DoLoadKeyedGeneric(HLoadKeyedGeneric* instr) { LOperand* LChunkBuilder::GetStoreKeyedValueOperand(HStoreKeyed* instr) { ElementsKind elements_kind = instr->elements_kind(); + BuiltinFunctionId op = instr->op(); // Determine if we need a byte register in this case for the value. bool val_is_fixed_register = - elements_kind == EXTERNAL_INT8_ELEMENTS || + (elements_kind == EXTERNAL_INT8_ELEMENTS || elements_kind == EXTERNAL_UINT8_ELEMENTS || elements_kind == EXTERNAL_UINT8_CLAMPED_ELEMENTS || elements_kind == UINT8_ELEMENTS || elements_kind == INT8_ELEMENTS || - elements_kind == UINT8_CLAMPED_ELEMENTS; + elements_kind == UINT8_CLAMPED_ELEMENTS) && + (op != kInt8ArraySetFloat32x4XYZW && + op != kInt8ArraySetFloat32x4X && + op != kInt8ArraySetFloat32x4XY && + op != kInt8ArraySetFloat32x4XYZ && + op != kInt8ArraySetInt32x4XYZW && + op != kInt8ArraySetInt32x4X && + op != kInt8ArraySetInt32x4XY && + op != kInt8ArraySetInt32x4XYZ && + op != kInt8ArraySetFloat64x2XY && + op != kInt8ArraySetFloat64x2X); if (val_is_fixed_register) { return UseFixed(instr->value(), eax); } diff --git a/src/v8/src/ia32/lithium-ia32.h b/src/v8/src/ia32/lithium-ia32.h index ec29698..6ade815 100644 --- a/src/v8/src/ia32/lithium-ia32.h +++ b/src/v8/src/ia32/lithium-ia32.h @@ -1409,15 +1409,20 @@ class LInstanceOfKnownGlobal FINAL : public LTemplateInstruction<1, 2, 1> { }; -class LBoundsCheck FINAL : public LTemplateInstruction<0, 2, 0> { +class LBoundsCheck FINAL : public LTemplateInstruction<0, 2, 2> { public: - LBoundsCheck(LOperand* index, LOperand* length) { + LBoundsCheck(LOperand* index, LOperand* length, + LOperand* temp0, LOperand* temp1) { inputs_[0] = index; inputs_[1] = length; + temps_[0] = temp0; + temps_[1] = temp1; } LOperand* index() { return inputs_[0]; } LOperand* length() { return inputs_[1]; } + LOperand* temp0() { return temps_[0]; } + LOperand* temp1() { return temps_[1]; } DECLARE_CONCRETE_INSTRUCTION(BoundsCheck, "bounds-check") DECLARE_HYDROGEN_ACCESSOR(BoundsCheck) diff --git a/src/v8/src/mips/assembler-mips-inl.h b/src/v8/src/mips/assembler-mips-inl.h index 2666f6a..1a4a6c5 100644 --- a/src/v8/src/mips/assembler-mips-inl.h +++ b/src/v8/src/mips/assembler-mips-inl.h @@ -48,6 +48,7 @@ namespace internal { bool CpuFeatures::SupportsCrankshaft() { return IsSupported(FPU); } +bool CpuFeatures::SupportsSIMD128InCrankshaft() { return false; } // ----------------------------------------------------------------------------- diff --git a/src/v8/src/mips/assembler-mips.h b/src/v8/src/mips/assembler-mips.h index 5cdf16a..d8883d1 100644 --- a/src/v8/src/mips/assembler-mips.h +++ b/src/v8/src/mips/assembler-mips.h @@ -355,7 +355,6 @@ struct FPUControlRegister { const FPUControlRegister no_fpucreg = { kInvalidFPUControlRegister }; const FPUControlRegister FCSR = { kFCSRRegister }; - // ----------------------------------------------------------------------------- // Machine instruction Operands. diff --git a/src/v8/src/mips/deoptimizer-mips.cc b/src/v8/src/mips/deoptimizer-mips.cc index dd9832d..baa8ea8 100644 --- a/src/v8/src/mips/deoptimizer-mips.cc +++ b/src/v8/src/mips/deoptimizer-mips.cc @@ -116,6 +116,10 @@ void Deoptimizer::CopyDoubleRegisters(FrameDescription* output_frame) { } +void Deoptimizer::CopySIMD128Registers(FrameDescription* output_frame) { +} + + bool Deoptimizer::HasAlignmentPadding(JSFunction* function) { // There is no dynamic alignment padding on MIPS in the input frame. return false; @@ -396,6 +400,41 @@ void FrameDescription::SetCallerConstantPool(unsigned offset, intptr_t value) { } +double FrameDescription::GetDoubleRegister(unsigned n) const { + DCHECK(n < arraysize(double_registers_)); + return double_registers_[n]; +} + + +void FrameDescription::SetDoubleRegister(unsigned n, double value) { + DCHECK(n < arraysize(double_registers_)); + double_registers_[n] = value; +} + + +simd128_value_t FrameDescription::GetSIMD128Register(unsigned n) const { + UNREACHABLE(); + simd128_value_t value; + return value; +} + + +void FrameDescription::SetSIMD128Register(unsigned n, simd128_value_t value) { + UNREACHABLE(); +} + + +int FrameDescription::double_registers_offset() { + return OFFSET_OF(FrameDescription, double_registers_); +} + + +int FrameDescription::simd128_registers_offset() { + UNREACHABLE(); + return -1; +} + + #undef __ diff --git a/src/v8/src/mips/lithium-codegen-mips.cc b/src/v8/src/mips/lithium-codegen-mips.cc index 497d10f..92fc10e 100644 --- a/src/v8/src/mips/lithium-codegen-mips.cc +++ b/src/v8/src/mips/lithium-codegen-mips.cc @@ -3189,10 +3189,16 @@ void LCodeGen::DoLoadKeyedExternalArray(LLoadKeyed* instr) { DeoptimizeIf(Ugreater_equal, instr, result, Operand(0x80000000)); } break; + case INT32x4_ELEMENTS: case FLOAT32_ELEMENTS: + case FLOAT32x4_ELEMENTS: case FLOAT64_ELEMENTS: + case FLOAT64x2_ELEMENTS: + case EXTERNAL_INT32x4_ELEMENTS: case EXTERNAL_FLOAT32_ELEMENTS: + case EXTERNAL_FLOAT32x4_ELEMENTS: case EXTERNAL_FLOAT64_ELEMENTS: + case EXTERNAL_FLOAT64x2_ELEMENTS: case FAST_DOUBLE_ELEMENTS: case FAST_ELEMENTS: case FAST_SMI_ELEMENTS: @@ -4280,10 +4286,16 @@ void LCodeGen::DoStoreKeyedExternalArray(LStoreKeyed* instr) { case UINT32_ELEMENTS: __ sw(value, mem_operand); break; + case INT32x4_ELEMENTS: case FLOAT32_ELEMENTS: + case FLOAT32x4_ELEMENTS: case FLOAT64_ELEMENTS: + case FLOAT64x2_ELEMENTS: + case EXTERNAL_INT32x4_ELEMENTS: case EXTERNAL_FLOAT32_ELEMENTS: + case EXTERNAL_FLOAT32x4_ELEMENTS: case EXTERNAL_FLOAT64_ELEMENTS: + case EXTERNAL_FLOAT64x2_ELEMENTS: case FAST_DOUBLE_ELEMENTS: case FAST_ELEMENTS: case FAST_SMI_ELEMENTS: diff --git a/src/v8/src/mips/lithium-mips.cc b/src/v8/src/mips/lithium-mips.cc index 1757d92..346a5e2 100644 --- a/src/v8/src/mips/lithium-mips.cc +++ b/src/v8/src/mips/lithium-mips.cc @@ -1226,6 +1226,41 @@ LInstruction* LChunkBuilder::DoMathRound(HUnaryMathOperation* instr) { } +LInstruction* LChunkBuilder::DoNullarySIMDOperation( + HNullarySIMDOperation* instr) { + UNIMPLEMENTED(); + return NULL; +} + + +LInstruction* LChunkBuilder::DoUnarySIMDOperation( + HUnarySIMDOperation* instr) { + UNIMPLEMENTED(); + return NULL; +} + + +LInstruction* LChunkBuilder::DoBinarySIMDOperation( + HBinarySIMDOperation* instr) { + UNIMPLEMENTED(); + return NULL; +} + + +LInstruction* LChunkBuilder::DoTernarySIMDOperation( + HTernarySIMDOperation* instr) { + UNIMPLEMENTED(); + return NULL; +} + + +LInstruction* LChunkBuilder::DoQuarternarySIMDOperation( + HQuarternarySIMDOperation* instr) { + UNIMPLEMENTED(); + return NULL; +} + + LInstruction* LChunkBuilder::DoCallNew(HCallNew* instr) { LOperand* context = UseFixed(instr->context(), cp); LOperand* constructor = UseFixed(instr->constructor(), a1); diff --git a/src/v8/src/objects.h b/src/v8/src/objects.h index 7e38e48..669217e 100644 --- a/src/v8/src/objects.h +++ b/src/v8/src/objects.h @@ -5845,7 +5845,7 @@ class Map: public HeapObject { inline bool is_prototype_map(); inline void set_elements_kind(ElementsKind elements_kind) { - DCHECK(elements_kind < kElementsKindCount); + DCHECK(static_cast(elements_kind) < kElementsKindCount); DCHECK(kElementsKindCount <= (1 << Map::ElementsKindBits::kSize)); set_bit_field2(Map::ElementsKindBits::update(bit_field2(), elements_kind)); DCHECK(this->elements_kind() == elements_kind); @@ -6822,6 +6822,50 @@ class Script: public Struct { V(Int32x4Array.prototype, getAt, Int32x4ArrayGetAt) \ V(Int32x4Array.prototype, setAt, Int32x4ArraySetAt) +#define TYPED_ARRAYS_SIMD_LOAD_OPERATIONS(V) \ + V(Float32Array.prototype, _getFloat32x4XYZW, Float32ArrayGetFloat32x4XYZW) \ + V(Float32Array.prototype, _getFloat32x4XYZ, Float32ArrayGetFloat32x4XYZ) \ + V(Float32Array.prototype, _getFloat32x4XY, Float32ArrayGetFloat32x4XY) \ + V(Float32Array.prototype, _getFloat32x4X, Float32ArrayGetFloat32x4X) \ + V(Float64Array.prototype, _getFloat64x2XY, Float64ArrayGetFloat64x2XY) \ + V(Float64Array.prototype, _getFloat64x2X, Float64ArrayGetFloat64x2X) \ + V(Int32Array.prototype, _getInt32x4XYZW, Int32ArrayGetInt32x4XYZW) \ + V(Int32Array.prototype, _getInt32x4XYZ, Int32ArrayGetInt32x4XYZ) \ + V(Int32Array.prototype, _getInt32x4XY, Int32ArrayGetInt32x4XY) \ + V(Int32Array.prototype, _getInt32x4X, Int32ArrayGetInt32x4X) \ + V(Int8Array.prototype, _getFloat32x4XYZW, Int8ArrayGetFloat32x4XYZW) \ + V(Int8Array.prototype, _getFloat32x4XYZ, Int8ArrayGetFloat32x4XYZ) \ + V(Int8Array.prototype, _getFloat32x4XY, Int8ArrayGetFloat32x4XY) \ + V(Int8Array.prototype, _getFloat32x4X, Int8ArrayGetFloat32x4X) \ + V(Int8Array.prototype, _getFloat64x2XY, Int8ArrayGetFloat64x2XY) \ + V(Int8Array.prototype, _getFloat64x2X, Int8ArrayGetFloat64x2X) \ + V(Int8Array.prototype, _getInt32x4XYZW, Int8ArrayGetInt32x4XYZW) \ + V(Int8Array.prototype, _getInt32x4XYZ, Int8ArrayGetInt32x4XYZ) \ + V(Int8Array.prototype, _getInt32x4XY, Int8ArrayGetInt32x4XY) \ + V(Int8Array.prototype, _getInt32x4X, Int8ArrayGetInt32x4X) + +#define TYPED_ARRAYS_SIMD_STORE_OPERATIONS(V) \ + V(Float32Array.prototype, _setFloat32x4XYZW, Float32ArraySetFloat32x4XYZW) \ + V(Float32Array.prototype, _setFloat32x4XYZ, Float32ArraySetFloat32x4XYZ) \ + V(Float32Array.prototype, _setFloat32x4XY, Float32ArraySetFloat32x4XY) \ + V(Float32Array.prototype, _setFloat32x4X, Float32ArraySetFloat32x4X) \ + V(Float64Array.prototype, _setFloat64x2XY, Float64ArraySetFloat64x2XY) \ + V(Float64Array.prototype, _setFloat64x2X, Float64ArraySetFloat64x2X) \ + V(Int32Array.prototype, _setInt32x4XYZW, Int32ArraySetInt32x4XYZW) \ + V(Int32Array.prototype, _setInt32x4XYZ, Int32ArraySetInt32x4XYZ) \ + V(Int32Array.prototype, _setInt32x4XY, Int32ArraySetInt32x4XY) \ + V(Int32Array.prototype, _setInt32x4X, Int32ArraySetInt32x4X) \ + V(Int8Array.prototype, _setFloat32x4XYZW, Int8ArraySetFloat32x4XYZW) \ + V(Int8Array.prototype, _setFloat32x4XYZ, Int8ArraySetFloat32x4XYZ) \ + V(Int8Array.prototype, _setFloat32x4XY, Int8ArraySetFloat32x4XY) \ + V(Int8Array.prototype, _setFloat32x4X, Int8ArraySetFloat32x4X) \ + V(Int8Array.prototype, _setFloat64x2XY, Int8ArraySetFloat64x2XY) \ + V(Int8Array.prototype, _setFloat64x2X, Int8ArraySetFloat64x2X) \ + V(Int8Array.prototype, _setInt32x4XYZW, Int8ArraySetInt32x4XYZW) \ + V(Int8Array.prototype, _setInt32x4XYZ, Int8ArraySetInt32x4XYZ) \ + V(Int8Array.prototype, _setInt32x4XY, Int8ArraySetInt32x4XY) \ + V(Int8Array.prototype, _setInt32x4X, Int8ArraySetInt32x4X) + // Do not need to install them in InstallExperimentalSIMDBuiltinFunctionIds. #define SIMD_FAKE_ID_LISTS(V) \ V(SIMD, unreachable, SIMD128Unreachable) \ @@ -6837,6 +6881,8 @@ enum BuiltinFunctionId { kMathPowHalf, SIMD_FAKE_ID_LISTS(DECLARE_FUNCTION_ID) SIMD_ARRAY_OPERATIONS(DECLARE_FUNCTION_ID) + TYPED_ARRAYS_SIMD_LOAD_OPERATIONS(DECLARE_FUNCTION_ID) + TYPED_ARRAYS_SIMD_STORE_OPERATIONS(DECLARE_FUNCTION_ID) #undef DECLARE_FUNCTION_ID #define DECLARE_SIMD_NULLARY_FUNCTION_ID(i1, i2, name, i3) \ k##name, diff --git a/src/v8/src/parser.cc b/src/v8/src/parser.cc index 7cef210..fbb5c51 100644 --- a/src/v8/src/parser.cc +++ b/src/v8/src/parser.cc @@ -491,6 +491,187 @@ bool ParserTraits::ShortcutNumericLiteralBinaryExpression( } +bool ParserTraits::BuildSIMD128LoadStoreExpression( + Expression** expression, ZoneList* arguments, int pos, + AstNodeFactory* factory) { + Property* prop = (*expression)->AsProperty(); + Expression* tarray_op_literal = NULL; + + if (prop) { + Property* simd_type_prop = prop->obj()->AsProperty(); + if (simd_type_prop) { + VariableProxy* simd_var = simd_type_prop->obj()->AsVariableProxy(); + if (simd_var && simd_var->raw_name() && + simd_var->raw_name()->IsOneByteEqualTo("SIMD")) { + Literal* type_literal = simd_type_prop->key()->AsLiteral(); + if (type_literal && type_literal->raw_value() && + type_literal->raw_value()->AsString()) { + const AstRawString* type_literal_raw_string = + type_literal->raw_value()->AsString(); + if (type_literal_raw_string->IsOneByteEqualTo("float32x4")) { + Literal* op_literal = prop->key()->AsLiteral(); + if (op_literal && op_literal->raw_value() && + op_literal->raw_value()->AsString()) { + const AstRawString* op_raw_string = + op_literal->raw_value()->AsString(); + AstValueFactory* ast_factory = parser_->ast_value_factory(); + if (op_raw_string->IsOneByteEqualTo("load")) { + const AstRawString* op_str = + ast_factory->GetOneByteString("_getFloat32x4XYZW"); + tarray_op_literal = + factory->NewStringLiteral(op_str, RelocInfo::kNoPosition); + } else if (op_raw_string->IsOneByteEqualTo("loadX")) { + const AstRawString* op_str = + ast_factory->GetOneByteString("_getFloat32x4X"); + tarray_op_literal = + factory->NewStringLiteral(op_str, RelocInfo::kNoPosition); + } else if (op_raw_string->IsOneByteEqualTo("loadXY")) { + const AstRawString* op_str = + ast_factory->GetOneByteString("_getFloat32x4XY"); + tarray_op_literal = + factory->NewStringLiteral(op_str, RelocInfo::kNoPosition); + } else if (op_raw_string->IsOneByteEqualTo("loadXYZ")) { + const AstRawString* op_str = + ast_factory->GetOneByteString("_getFloat32x4XYZ"); + tarray_op_literal = + factory->NewStringLiteral(op_str, RelocInfo::kNoPosition); + } else if (op_raw_string->IsOneByteEqualTo("store")) { + const AstRawString* op_str = + ast_factory->GetOneByteString("_setFloat32x4XYZW"); + tarray_op_literal = + factory->NewStringLiteral(op_str, RelocInfo::kNoPosition); + } else if (op_raw_string->IsOneByteEqualTo("storeX")) { + const AstRawString* op_str = + ast_factory->GetOneByteString("_setFloat32x4X"); + tarray_op_literal = + factory->NewStringLiteral(op_str, RelocInfo::kNoPosition); + } else if (op_raw_string->IsOneByteEqualTo("storeXY")) { + const AstRawString* op_str = + ast_factory->GetOneByteString("_setFloat32x4XY"); + tarray_op_literal = + factory->NewStringLiteral(op_str, RelocInfo::kNoPosition); + } else if (op_raw_string->IsOneByteEqualTo("storeXYZ")) { + const AstRawString* op_str = + ast_factory->GetOneByteString("_setFloat32x4XYZ"); + tarray_op_literal = + factory->NewStringLiteral(op_str, RelocInfo::kNoPosition); + } + } + } else if (type_literal_raw_string->IsOneByteEqualTo("int32x4")) { + Literal* op_literal = prop->key()->AsLiteral(); + if (op_literal && op_literal->raw_value() && + op_literal->raw_value()->AsString()) { + const AstRawString* op_raw_string = + op_literal->raw_value()->AsString(); + AstValueFactory* ast_factory = parser_->ast_value_factory(); + if (op_raw_string->IsOneByteEqualTo("load")) { + const AstRawString* op_str = + ast_factory->GetOneByteString("_getInt32x4XYZW"); + tarray_op_literal = + factory->NewStringLiteral(op_str, RelocInfo::kNoPosition); + } else if (op_raw_string->IsOneByteEqualTo("loadX")) { + const AstRawString* op_str = + ast_factory->GetOneByteString("_getInt32x4X"); + tarray_op_literal = + factory->NewStringLiteral(op_str, RelocInfo::kNoPosition); + } else if (op_raw_string->IsOneByteEqualTo("loadXY")) { + const AstRawString* op_str = + ast_factory->GetOneByteString("_getInt32x4XY"); + tarray_op_literal = + factory->NewStringLiteral(op_str, RelocInfo::kNoPosition); + } else if (op_raw_string->IsOneByteEqualTo("loadXYZ")) { + const AstRawString* op_str = + ast_factory->GetOneByteString("_getInt32x4XYZ"); + tarray_op_literal = + factory->NewStringLiteral(op_str, RelocInfo::kNoPosition); + } else if (op_raw_string->IsOneByteEqualTo("store")) { + const AstRawString* op_str = + ast_factory->GetOneByteString("_setInt32x4XYZW"); + tarray_op_literal = + factory->NewStringLiteral(op_str, RelocInfo::kNoPosition); + } else if (op_raw_string->IsOneByteEqualTo("storeX")) { + const AstRawString* op_str = + ast_factory->GetOneByteString("_setInt32x4X"); + tarray_op_literal = + factory->NewStringLiteral(op_str, RelocInfo::kNoPosition); + } else if (op_raw_string->IsOneByteEqualTo("storeXY")) { + const AstRawString* op_str = + ast_factory->GetOneByteString("_setInt32x4XY"); + tarray_op_literal = + factory->NewStringLiteral(op_str, RelocInfo::kNoPosition); + } else if (op_raw_string->IsOneByteEqualTo("storeXYZ")) { + const AstRawString* op_str = + ast_factory->GetOneByteString("_setInt32x4XYZ"); + tarray_op_literal = + factory->NewStringLiteral(op_str, RelocInfo::kNoPosition); + } + } + } else if (type_literal_raw_string->IsOneByteEqualTo("float64x2")) { + Literal* op_literal = prop->key()->AsLiteral(); + if (op_literal && op_literal->raw_value() && + op_literal->raw_value()->AsString()) { + const AstRawString* op_raw_string = + op_literal->raw_value()->AsString(); + AstValueFactory* ast_factory = parser_->ast_value_factory(); + if (op_raw_string->IsOneByteEqualTo("load")) { + const AstRawString* op_str = + ast_factory->GetOneByteString("_getFloat64x2XY"); + tarray_op_literal = + factory->NewStringLiteral(op_str, RelocInfo::kNoPosition); + } else if (op_raw_string->IsOneByteEqualTo("loadX")) { + const AstRawString* op_str = + ast_factory->GetOneByteString("_getFloat64x2X"); + tarray_op_literal = + factory->NewStringLiteral(op_str, RelocInfo::kNoPosition); + } else if (op_raw_string->IsOneByteEqualTo("store")) { + const AstRawString* op_str = + ast_factory->GetOneByteString("_setFloat64x2XY"); + tarray_op_literal = + factory->NewStringLiteral(op_str, RelocInfo::kNoPosition); + } else if (op_raw_string->IsOneByteEqualTo("storeX")) { + const AstRawString* op_str = + ast_factory->GetOneByteString("_setFloat64x2X"); + tarray_op_literal = + factory->NewStringLiteral(op_str, RelocInfo::kNoPosition); + } + } + } + } + } + } + } + + if (tarray_op_literal) { + if (arguments && arguments->length() == 2) { + Expression* tarray = arguments->at(0); + Expression* index = arguments->at(1); + Expression* tarray_op = + factory->NewProperty(tarray, tarray_op_literal, pos); + Zone* zone = parser_->zone(); + ZoneList* tarray_op_args = + new (zone) ZoneList(1, zone); + tarray_op_args->Add(index, zone); + *expression = factory->NewCall(tarray_op, tarray_op_args, pos); + return true; + } else if (arguments && arguments->length() == 3) { + Expression* tarray = arguments->at(0); + Expression* index = arguments->at(1); + Expression* value = arguments->at(2); + Expression* tarray_op = + factory->NewProperty(tarray, tarray_op_literal, pos); + Zone* zone = parser_->zone(); + ZoneList* tarray_op_args = + new (zone) ZoneList(1, zone); + tarray_op_args->Add(index, zone); + tarray_op_args->Add(value, zone); + *expression = factory->NewCall(tarray_op, tarray_op_args, pos); + return true; + } + } + return false; +} + + Expression* ParserTraits::BuildUnaryExpression( Expression* expression, Token::Value op, int pos, AstNodeFactory* factory) { diff --git a/src/v8/src/parser.h b/src/v8/src/parser.h index 40886f6..1fe92b2 100644 --- a/src/v8/src/parser.h +++ b/src/v8/src/parser.h @@ -461,6 +461,14 @@ class ParserTraits { Expression** x, Expression* y, Token::Value op, int pos, AstNodeFactory* factory); + // If we find a SIMD load or store call with array types + // and offset as arguments, we will return an expression + // calling array types load or store with offset as argument. + // Otherwise, returns NULL. + bool BuildSIMD128LoadStoreExpression( + Expression** expression, ZoneList* arguments, int pos, + AstNodeFactory* factory); + // Rewrites the following types of unary expressions: // not -> true / false // + -> diff --git a/src/v8/src/preparser.h b/src/v8/src/preparser.h index 78f6a26..fa2cf5c 100644 --- a/src/v8/src/preparser.h +++ b/src/v8/src/preparser.h @@ -1232,6 +1232,14 @@ class PreParserTraits { return false; } + bool BuildSIMD128LoadStoreExpression( + PreParserExpression* expression, + PreParserExpressionList arguments, + int pos, + PreParserFactory* factory) { + return false; + } + PreParserExpression BuildUnaryExpression(PreParserExpression expression, Token::Value op, int pos, PreParserFactory* factory) { @@ -2433,6 +2441,10 @@ ParserBase::ParseLeftHandSideExpression(bool* ok) { } typename Traits::Type::ExpressionList args = ParseArguments(CHECK_OK); + if (this->BuildSIMD128LoadStoreExpression( + &result, args, pos, factory())) + break; + // Keep track of eval() calls since they disable all local variable // optimizations. // The calls that need special treatment are the diff --git a/src/v8/src/runtime.cc b/src/v8/src/runtime.cc index 2e51433..a992704 100644 --- a/src/v8/src/runtime.cc +++ b/src/v8/src/runtime.cc @@ -15450,6 +15450,132 @@ RUNTIME_FUNCTION_RETURN_PAIR(Runtime_ForInNext) { } +template +inline static bool SimdTypeLoadValue( + Isolate* isolate, + Handle buffer, + Handle byte_offset_obj, + T* result) { + size_t byte_offset = 0; + if (!TryNumberToSize(isolate, *byte_offset_obj, &byte_offset)) { + return false; + } + + size_t buffer_byte_length = + NumberToSize(isolate, buffer->byte_length()); + if (byte_offset + Bytes > buffer_byte_length) { // overflow + return false; + } + + union Value { + T data; + uint8_t bytes[sizeof(T)]; + }; + + Value value; + memset(value.bytes, 0, sizeof(T)); + uint8_t* source = + static_cast(buffer->backing_store()) + byte_offset; + DCHECK(Bytes <= sizeof(T)); + CopyBytes(value.bytes, source); + *result = value.data; + return true; +} + + +template +static bool SimdTypeStoreValue( + Isolate* isolate, + Handle buffer, + Handle byte_offset_obj, + T data) { + size_t byte_offset = 0; + if (!TryNumberToSize(isolate, *byte_offset_obj, &byte_offset)) { + return false; + } + + size_t buffer_byte_length = + NumberToSize(isolate, buffer->byte_length()); + if (byte_offset + Bytes > buffer_byte_length) { // overflow + return false; + } + + union Value { + T data; + uint8_t bytes[sizeof(T)]; + }; + + Value value; + value.data = data; + + uint8_t* target = + static_cast(buffer->backing_store()) + byte_offset; + DCHECK(Bytes <= sizeof(T)); + CopyBytes(target, value.bytes); + return true; +} + + +#define SIMD128_LOAD_RUNTIME_FUNCTION(Type, ValueType, Lanes, Bytes) \ +RUNTIME_FUNCTION(Runtime_##Type##Load##Lanes) { \ + HandleScope scope(isolate); \ + DCHECK(args.length() == 2); \ + CONVERT_ARG_HANDLE_CHECKED(JSArrayBuffer, buffer, 0); \ + CONVERT_NUMBER_ARG_HANDLE_CHECKED(offset, 1); \ + ValueType result; \ + if (SimdTypeLoadValue( \ + isolate, buffer, offset, &result)) { \ + return *isolate->factory()->New##Type(result); \ + } else { \ + THROW_NEW_ERROR_RETURN_FAILURE( \ + isolate, NewRangeError("invalid_offset", \ + HandleVector(NULL, 0))); \ + } \ +} + + +SIMD128_LOAD_RUNTIME_FUNCTION(Float32x4, float32x4_value_t, XYZW, 16) +SIMD128_LOAD_RUNTIME_FUNCTION(Float32x4, float32x4_value_t, XYZ, 12) +SIMD128_LOAD_RUNTIME_FUNCTION(Float32x4, float32x4_value_t, XY, 8) +SIMD128_LOAD_RUNTIME_FUNCTION(Float32x4, float32x4_value_t, X, 4) +SIMD128_LOAD_RUNTIME_FUNCTION(Float64x2, float64x2_value_t, XY, 16) +SIMD128_LOAD_RUNTIME_FUNCTION(Float64x2, float64x2_value_t, X, 8) +SIMD128_LOAD_RUNTIME_FUNCTION(Int32x4, int32x4_value_t, XYZW, 16) +SIMD128_LOAD_RUNTIME_FUNCTION(Int32x4, int32x4_value_t, XYZ, 12) +SIMD128_LOAD_RUNTIME_FUNCTION(Int32x4, int32x4_value_t, XY, 8) +SIMD128_LOAD_RUNTIME_FUNCTION(Int32x4, int32x4_value_t, X, 4) + + +#define SIMD128_STORE_RUNTIME_FUNCTION(Type, ValueType, Lanes, Bytes) \ +RUNTIME_FUNCTION(Runtime_##Type##Store##Lanes) { \ + HandleScope scope(isolate); \ + DCHECK(args.length() == 3); \ + CONVERT_ARG_HANDLE_CHECKED(JSArrayBuffer, buffer, 0); \ + CONVERT_NUMBER_ARG_HANDLE_CHECKED(offset, 1); \ + CONVERT_ARG_CHECKED(Type, value, 2); \ + ValueType v = value->get(); \ + if (SimdTypeStoreValue(isolate, buffer, offset, v)) { \ + return isolate->heap()->undefined_value(); \ + } else { \ + THROW_NEW_ERROR_RETURN_FAILURE( \ + isolate, NewRangeError("invalid_offset", \ + HandleVector(NULL, 0))); \ + } \ +} + + +SIMD128_STORE_RUNTIME_FUNCTION(Float32x4, float32x4_value_t, XYZW, 16) +SIMD128_STORE_RUNTIME_FUNCTION(Float32x4, float32x4_value_t, XYZ, 12) +SIMD128_STORE_RUNTIME_FUNCTION(Float32x4, float32x4_value_t, XY, 8) +SIMD128_STORE_RUNTIME_FUNCTION(Float32x4, float32x4_value_t, X, 4) +SIMD128_STORE_RUNTIME_FUNCTION(Float64x2, float64x2_value_t, XY, 16) +SIMD128_STORE_RUNTIME_FUNCTION(Float64x2, float64x2_value_t, X, 8) +SIMD128_STORE_RUNTIME_FUNCTION(Int32x4, int32x4_value_t, XYZW, 16) +SIMD128_STORE_RUNTIME_FUNCTION(Int32x4, int32x4_value_t, XYZ, 12) +SIMD128_STORE_RUNTIME_FUNCTION(Int32x4, int32x4_value_t, XY, 8) +SIMD128_STORE_RUNTIME_FUNCTION(Int32x4, int32x4_value_t, X, 4) + + #define RETURN_Float32x4_RESULT(value) \ return *isolate->factory()->NewFloat32x4(value); diff --git a/src/v8/src/runtime.h b/src/v8/src/runtime.h index 477f8bd..5921ff7 100644 --- a/src/v8/src/runtime.h +++ b/src/v8/src/runtime.h @@ -157,6 +157,14 @@ namespace internal { F(AllocateInt32x4, 0, 1) \ \ /* SIMD */ \ + F(Float32x4LoadX, 2, 1) \ + F(Float32x4LoadXY, 2, 1) \ + F(Float32x4LoadXYZ, 2, 1) \ + F(Float32x4LoadXYZW, 2, 1) \ + F(Float32x4StoreX, 3, 1) \ + F(Float32x4StoreXY, 3, 1) \ + F(Float32x4StoreXYZ, 3, 1) \ + F(Float32x4StoreXYZW, 3, 1) \ F(Float32x4Abs, 1, 1) \ F(Float32x4BitsToInt32x4, 1, 1) \ F(Float32x4Neg, 1, 1) \ @@ -185,6 +193,10 @@ namespace internal { F(Float32x4Clamp, 3, 1) \ F(Float32x4ShuffleMix, 3, 1) \ F(Float32x4Select, 3, 1) \ + F(Float64x2LoadX, 2, 1) \ + F(Float64x2LoadXY, 2, 1) \ + F(Float64x2StoreX, 3, 1) \ + F(Float64x2StoreXY, 3, 1) \ F(Float64x2Abs, 1, 1) \ F(Float64x2Neg, 1, 1) \ F(Float64x2Sqrt, 1, 1) \ @@ -198,6 +210,14 @@ namespace internal { F(Float64x2WithX, 2, 1) \ F(Float64x2WithY, 2, 1) \ F(Float64x2Clamp, 3, 1) \ + F(Int32x4LoadX, 2, 1) \ + F(Int32x4LoadXY, 2, 1) \ + F(Int32x4LoadXYZ, 2, 1) \ + F(Int32x4LoadXYZW, 2, 1) \ + F(Int32x4StoreX, 3, 1) \ + F(Int32x4StoreXY, 3, 1) \ + F(Int32x4StoreXYZ, 3, 1) \ + F(Int32x4StoreXYZW, 3, 1) \ F(Int32x4BitsToFloat32x4, 1, 1) \ F(Int32x4Neg, 1, 1) \ F(Int32x4Not, 1, 1) \ diff --git a/src/v8/src/simd128.js b/src/v8/src/simd128.js index 2ac352f..e7ce888 100644 --- a/src/v8/src/simd128.js +++ b/src/v8/src/simd128.js @@ -343,6 +343,10 @@ FLOAT64x2_BINARY_FUNCTIONS_WITH_FLOAT64_PARAMETER(DECLARE_FLOAT64x2_BINARY_FUNCT INT32x4_BINARY_FUNCTIONS_WITH_INT32_PARAMETER(DECLARE_INT32x4_BINARY_FUNCTION_WITH_INT32_PARAMETER) INT32x4_BINARY_FUNCTIONS_WITH_BOOLEAN_PARAMETER(DECLARE_INT32x4_BINARY_FUNCTION_WITH_BOOLEAN_PARAMETER) +function NotImplementedJS() { + throw MakeTypeError("Not implemented."); +} + function Float32x4SplatJS(f) { f = TO_NUMBER_INLINE(f); return %CreateFloat32x4(f, f, f, f); @@ -735,6 +739,14 @@ function SetUpSIMD() { // Set up non-enumerable properties of the SIMD float32x4 object. InstallFunctions($SIMD.float32x4, DONT_ENUM, $Array( // Float32x4 operations + "load", NotImplementedJS, + "loadX", NotImplementedJS, + "loadXY", NotImplementedJS, + "loadXYZ", NotImplementedJS, + "store", NotImplementedJS, + "storeX", NotImplementedJS, + "storeXY", NotImplementedJS, + "storeXYZ", NotImplementedJS, "splat", Float32x4SplatJS, "zero", Float32x4ZeroJS, // Unary @@ -777,6 +789,10 @@ function SetUpSIMD() { // Set up non-enumerable properties of the SIMD float64x2 object. InstallFunctions($SIMD.float64x2, DONT_ENUM, $Array( // Float64x2 operations + "load", NotImplementedJS, + "loadX", NotImplementedJS, + "store", NotImplementedJS, + "storeX", NotImplementedJS, "splat", Float64x2SplatJS, "zero", Float64x2ZeroJS, // Unary @@ -800,6 +816,14 @@ function SetUpSIMD() { // Set up non-enumerable properties of the SIMD int32x4 object. InstallFunctions($SIMD.int32x4, DONT_ENUM, $Array( // Int32x4 operations + "load", NotImplementedJS, + "loadX", NotImplementedJS, + "loadXY", NotImplementedJS, + "loadXYZ", NotImplementedJS, + "store", NotImplementedJS, + "storeX", NotImplementedJS, + "storeXY", NotImplementedJS, + "storeXYZ", NotImplementedJS, "zero", Int32x4ZeroJS, "splat", Int32x4SplatJS, "bool", Int32x4BoolJS, @@ -1061,3 +1085,116 @@ DECLARE_TYPED_ARRAY_FUNCTION(Int32x4) SetUpFloat32x4Array(); SetUpFloat64x2Array(); SetUpInt32x4Array(); + +// --------------------SIMD128 Access in Typed Array ----------------- +var $Uint8Array = global.Uint8Array; +var $Int8Array = global.Int8Array; +var $Uint16Array = global.Uint16Array; +var $Int16Array = global.Int16Array; +var $Uint32Array = global.Uint32Array; +var $Int32Array = global.Int32Array; +var $Float32Array = global.Float32Array; +var $Float64Array = global.Float64Array; + +macro DECLARE_TYPED_ARRAY_SIMD_LOAD_AND_STORE_FUNCTION(VIEW, TYPE, LANES, NBYTES) +function VIEWGetTYPELANESJS(index) { + if (!(%_ClassOf(this) === 'VIEW')) { + throw MakeTypeError('incompatible_method_receiver', + ["VIEW._getTYPELANES", this]); + } + var tarray = this; + if (%_ArgumentsLength() < 1) { + throw MakeTypeError('invalid_argument'); + } + if (!IS_NUMBER(index)) { + throw MakeTypeError('The 2nd argument must be a Number.'); + } + var offset = TO_INTEGER(index) * tarray.BYTES_PER_ELEMENT; + if (offset < 0 || (offset + NBYTES) > tarray.byteLength) + throw MakeRangeError('The value of index is invalid.'); + var arraybuffer = tarray.buffer; + return %TYPELoadLANES(arraybuffer, offset); +} + +function VIEWSetTYPELANESJS(index, value) { + if (!(%_ClassOf(this) === 'VIEW')) { + throw MakeTypeError('incompatible_method_receiver', + ["VIEW._setTYPELANES", this]); + } + var tarray = this; + if (%_ArgumentsLength() < 2) { + throw MakeTypeError('invalid_argument'); + } + if (!IS_NUMBER(index)) { + throw MakeTypeError('The 2nd argument must be a Number.'); + } + CheckTYPE(value); + var offset = TO_INTEGER(index) * tarray.BYTES_PER_ELEMENT; + if (offset < 0 || (offset + NBYTES) > tarray.byteLength) + throw MakeRangeError('The value of index is invalid.'); + var arraybuffer = tarray.buffer; + %TYPEStoreLANES(arraybuffer, offset, value); +} +endmacro + +macro DECLARE_VIEW_SIMD_LOAD_AND_STORE_FUNCTION(VIEW) +DECLARE_TYPED_ARRAY_SIMD_LOAD_AND_STORE_FUNCTION(VIEW, Float32x4, XYZW, 12) +DECLARE_TYPED_ARRAY_SIMD_LOAD_AND_STORE_FUNCTION(VIEW, Float32x4, XYZ, 12) +DECLARE_TYPED_ARRAY_SIMD_LOAD_AND_STORE_FUNCTION(VIEW, Float32x4, XY, 8) +DECLARE_TYPED_ARRAY_SIMD_LOAD_AND_STORE_FUNCTION(VIEW, Float32x4, X, 4) +DECLARE_TYPED_ARRAY_SIMD_LOAD_AND_STORE_FUNCTION(VIEW, Float64x2, XY, 16) +DECLARE_TYPED_ARRAY_SIMD_LOAD_AND_STORE_FUNCTION(VIEW, Float64x2, X, 8) +DECLARE_TYPED_ARRAY_SIMD_LOAD_AND_STORE_FUNCTION(VIEW, Int32x4, XYZW, 16) +DECLARE_TYPED_ARRAY_SIMD_LOAD_AND_STORE_FUNCTION(VIEW, Int32x4, XYZ, 12) +DECLARE_TYPED_ARRAY_SIMD_LOAD_AND_STORE_FUNCTION(VIEW, Int32x4, XY, 8) +DECLARE_TYPED_ARRAY_SIMD_LOAD_AND_STORE_FUNCTION(VIEW, Int32x4, X, 4) +endmacro + +DECLARE_VIEW_SIMD_LOAD_AND_STORE_FUNCTION(Uint8Array) +DECLARE_VIEW_SIMD_LOAD_AND_STORE_FUNCTION(Int8Array) +DECLARE_VIEW_SIMD_LOAD_AND_STORE_FUNCTION(Uint16Array) +DECLARE_VIEW_SIMD_LOAD_AND_STORE_FUNCTION(Int16Array) +DECLARE_VIEW_SIMD_LOAD_AND_STORE_FUNCTION(Uint32Array) +DECLARE_VIEW_SIMD_LOAD_AND_STORE_FUNCTION(Int32Array) +DECLARE_VIEW_SIMD_LOAD_AND_STORE_FUNCTION(Float32Array) +DECLARE_VIEW_SIMD_LOAD_AND_STORE_FUNCTION(Float64Array) + +function SetupTypedArraysSimdLoadStore() { + %CheckIsBootstrapping(); + +macro DECLARE_INSTALL_SIMD_LOAD_AND_STORE_FUNCTION(VIEW) + InstallFunctions($VIEW.prototype, DONT_ENUM, $Array( + "_getFloat32x4X", VIEWGetFloat32x4XJS, + "_setFloat32x4X", VIEWSetFloat32x4XJS, + "_getFloat32x4XY", VIEWGetFloat32x4XYJS, + "_setFloat32x4XY", VIEWSetFloat32x4XYJS, + "_getFloat32x4XYZ", VIEWGetFloat32x4XYZJS, + "_setFloat32x4XYZ", VIEWSetFloat32x4XYZJS, + "_getFloat32x4XYZW", VIEWGetFloat32x4XYZWJS, + "_setFloat32x4XYZW", VIEWSetFloat32x4XYZWJS, + "_getFloat64x2X", VIEWGetFloat64x2XJS, + "_setFloat64x2X", VIEWSetFloat64x2XJS, + "_getFloat64x2XY", VIEWGetFloat64x2XYJS, + "_setFloat64x2XY", VIEWSetFloat64x2XYJS, + "_getInt32x4X", VIEWGetInt32x4XJS, + "_setInt32x4X", VIEWSetInt32x4XJS, + "_getInt32x4XY", VIEWGetInt32x4XYJS, + "_setInt32x4XY", VIEWSetInt32x4XYJS, + "_getInt32x4XYZ", VIEWGetInt32x4XYZJS, + "_setInt32x4XYZ", VIEWSetInt32x4XYZJS, + "_getInt32x4XYZW", VIEWGetInt32x4XYZWJS, + "_setInt32x4XYZW", VIEWSetInt32x4XYZWJS + )); +endmacro + +DECLARE_INSTALL_SIMD_LOAD_AND_STORE_FUNCTION(Uint8Array) +DECLARE_INSTALL_SIMD_LOAD_AND_STORE_FUNCTION(Int8Array) +DECLARE_INSTALL_SIMD_LOAD_AND_STORE_FUNCTION(Uint16Array) +DECLARE_INSTALL_SIMD_LOAD_AND_STORE_FUNCTION(Int16Array) +DECLARE_INSTALL_SIMD_LOAD_AND_STORE_FUNCTION(Uint32Array) +DECLARE_INSTALL_SIMD_LOAD_AND_STORE_FUNCTION(Int32Array) +DECLARE_INSTALL_SIMD_LOAD_AND_STORE_FUNCTION(Float32Array) +DECLARE_INSTALL_SIMD_LOAD_AND_STORE_FUNCTION(Float64Array) +} + +SetupTypedArraysSimdLoadStore(); diff --git a/src/v8/src/x64/deoptimizer-x64.cc b/src/v8/src/x64/deoptimizer-x64.cc index ccd6a9c..2149fa5 100644 --- a/src/v8/src/x64/deoptimizer-x64.cc +++ b/src/v8/src/x64/deoptimizer-x64.cc @@ -113,6 +113,10 @@ void Deoptimizer::SetPlatformCompiledStubRegisters( } +void Deoptimizer::CopyDoubleRegisters(FrameDescription* output_frame) { +} + + void Deoptimizer::CopySIMD128Registers(FrameDescription* output_frame) { for (int i = 0; i < XMMRegister::NumAllocatableRegisters(); ++i) { simd128_value_t xmm_value = input_->GetSIMD128Register(i); @@ -359,6 +363,28 @@ void FrameDescription::SetDoubleRegister(unsigned n, double value) { } +simd128_value_t FrameDescription::GetSIMD128Register(unsigned n) const { + DCHECK(n < arraysize(simd128_registers_)); + return simd128_registers_[n]; +} + + +void FrameDescription::SetSIMD128Register(unsigned n, simd128_value_t value) { + DCHECK(n < arraysize(simd128_registers_)); + simd128_registers_[n] = value; +} + + +int FrameDescription::double_registers_offset() { + return OFFSET_OF(FrameDescription, simd128_registers_); +} + + +int FrameDescription::simd128_registers_offset() { + return OFFSET_OF(FrameDescription, simd128_registers_); +} + + #undef __ diff --git a/src/v8/test/mjsunit/simd/loadstore.js b/src/v8/test/mjsunit/simd/loadstore.js new file mode 100644 index 0000000..b5fd29c --- /dev/null +++ b/src/v8/test/mjsunit/simd/loadstore.js @@ -0,0 +1,253 @@ +// Copyright 2014 the V8 project authors. All rights reserved. +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following +// disclaimer in the documentation and/or other materials provided +// with the distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +// Flags: --simd_object --allow-natives-syntax + +function testFloat32x4LoadAndStore() { + var f32_array = new Float32Array(12); + for (var i = 0; i < 12; ++i) + f32_array[i] = 1.0 + i; + + var v1 = SIMD.float32x4.load(f32_array, 0); + var v2 = SIMD.float32x4.load(f32_array, 4); + var v3 = SIMD.float32x4.load(f32_array, 8); + + assertEquals(1.0, v1.x); + assertEquals(2.0, v1.y); + assertEquals(3.0, v1.z); + assertEquals(4.0, v1.w); + + assertEquals(5.0, v2.x); + assertEquals(6.0, v2.y); + assertEquals(7.0, v2.z); + assertEquals(8.0, v2.w); + + assertEquals(9.0, v3.x); + assertEquals(10.0, v3.y); + assertEquals(11.0, v3.z); + assertEquals(12.0, v3.w); + + SIMD.float32x4.store(f32_array, 0, SIMD.float32x4(12.0, 11.0, 10.0, 9.0)); + SIMD.float32x4.store(f32_array, 4, SIMD.float32x4(8.0, 7.0, 6.0, 5.0)); + SIMD.float32x4.store(f32_array, 8, SIMD.float32x4(4.0, 3.0, 2.0, 1.0)); + + for (var i = 0; i < 12; ++i) + assertEquals(12.0 - i, f32_array[i]); +} + +testFloat32x4LoadAndStore(); +testFloat32x4LoadAndStore(); +%OptimizeFunctionOnNextCall(testFloat32x4LoadAndStore); +testFloat32x4LoadAndStore(); + +function testFloat32x4LoadXAndStoreX() { + var f32_array = new Float32Array(12); + for (var i = 0; i < 12; ++i) + f32_array[i] = 1.0 + i; + + for (var i = 0; i < 12; ++i) { + var v = SIMD.float32x4.loadX(f32_array, i); + + assertEquals(1.0 + i, v.x); + assertEquals(0.0, v.y); + assertEquals(0.0, v.z); + assertEquals(0.0, v.w); + } + + for (var i = 0; i < 12; ++i) { + SIMD.float32x4.storeX(f32_array, i, SIMD.float32x4(12.0 - i, 0.0, 0.0, 0.0)); + } + + for (var i = 0; i < 12; ++i) + assertEquals(12.0 - i, f32_array[i]); +} + +testFloat32x4LoadXAndStoreX(); +testFloat32x4LoadXAndStoreX(); +%OptimizeFunctionOnNextCall(testFloat32x4LoadXAndStoreX); +testFloat32x4LoadXAndStoreX(); + +function testFloat32x4LoadXYAndStoreXY() { + var f32_array = new Float32Array(12); + for (var i = 0; i < 12; ++i) + f32_array[i] = 1.0 + i; + + for (var i = 0; i < 12; i += 2) { + var v = SIMD.float32x4.loadXY(f32_array, i); + + assertEquals(1.0 + i, v.x); + assertEquals(2.0 + i, v.y); + assertEquals(0.0, v.z); + assertEquals(0.0, v.w); + } + + for (var i = 0; i < 12; i += 2) { + SIMD.float32x4.storeXY(f32_array, i, SIMD.float32x4(12.0 - i, 11.0 - i, 0.0, 0.0)); + } + + for (var i = 0; i < 12; ++i) + assertEquals(12.0 - i, f32_array[i]); +} + +testFloat32x4LoadXYAndStoreXY(); +testFloat32x4LoadXYAndStoreXY(); +%OptimizeFunctionOnNextCall(testFloat32x4LoadXYAndStoreXY); +testFloat32x4LoadXYAndStoreXY(); + +function testFloat32x4LoadXYZAndStoreXYZ() { + var f32_array = new Float32Array(12); + for (var i = 0; i < 12; ++i) + f32_array[i] = 1.0 + i; + + for (var i = 0; i < 12; i += 3) { + var v = SIMD.float32x4.loadXYZ(f32_array, i); + + assertEquals(1.0 + i, v.x); + assertEquals(2.0 + i, v.y); + assertEquals(3.0 + i, v.z); + assertEquals(0.0, v.w); + } + + for (var i = 0; i < 12; i += 3) { + SIMD.float32x4.storeXYZ(f32_array, i, SIMD.float32x4(12.0 - i, 11.0 - i, 10.0 - i, 0.0)); + } + + for (var i = 0; i < 12; ++i) + assertEquals(12.0 - i, f32_array[i]); +} + +testFloat32x4LoadXYZAndStoreXYZ(); +testFloat32x4LoadXYZAndStoreXYZ(); +%OptimizeFunctionOnNextCall(testFloat32x4LoadXYZAndStoreXYZ); +testFloat32x4LoadXYZAndStoreXYZ(); + +function testFloat32x4LoadAndStoreFromInt8Array() { + var f32_array = new Float32Array(12); + for (var i = 0; i < 12; ++i) + f32_array[i] = 1.0 + i; + + var i8_array = new Int8Array(f32_array.buffer); + + var v1 = SIMD.float32x4.load(i8_array, 0); + var v2 = SIMD.float32x4.load(i8_array, 16); + var v3 = SIMD.float32x4.load(i8_array, 32); + + assertEquals(1.0, v1.x); + assertEquals(2.0, v1.y); + assertEquals(3.0, v1.z); + assertEquals(4.0, v1.w); + + assertEquals(5.0, v2.x); + assertEquals(6.0, v2.y); + assertEquals(7.0, v2.z); + assertEquals(8.0, v2.w); + + assertEquals(9.0, v3.x); + assertEquals(10.0, v3.y); + assertEquals(11.0, v3.z); + assertEquals(12.0, v3.w); + + SIMD.float32x4.store(i8_array, 0, SIMD.float32x4(12.0, 11.0, 10.0, 9.0)); + SIMD.float32x4.store(i8_array, 16, SIMD.float32x4(8.0, 7.0, 6.0, 5.0)); + SIMD.float32x4.store(i8_array, 32, SIMD.float32x4(4.0, 3.0, 2.0, 1.0)); + + for (var i = 0; i < 12; ++i) + assertEquals(12.0 - i, f32_array[i]); +} + +testFloat32x4LoadAndStoreFromInt8Array(); +testFloat32x4LoadAndStoreFromInt8Array(); +%OptimizeFunctionOnNextCall(testFloat32x4LoadAndStoreFromInt8Array); +testFloat32x4LoadAndStoreFromInt8Array(); + +function testFloat64x2LoadAndStore() { + var f64_array = new Float64Array(6); + for (var i = 0; i < 6; ++i) + f64_array[i] = 1.0 + i; + + var v1 = SIMD.float64x2.load(f64_array, 0); + var v2 = SIMD.float64x2.load(f64_array, 2); + var v3 = SIMD.float64x2.load(f64_array, 4); + + assertEquals(1.0, v1.x); + assertEquals(2.0, v1.y); + + assertEquals(3.0, v2.x); + assertEquals(4.0, v2.y); + + assertEquals(5.0, v3.x); + assertEquals(6.0, v3.y); + + SIMD.float64x2.store(f64_array, 0, SIMD.float64x2(6.0, 5.0)); + SIMD.float64x2.store(f64_array, 2, SIMD.float64x2(4.0, 3.0)); + SIMD.float64x2.store(f64_array, 4, SIMD.float64x2(2.0, 1.0)); + + for (var i = 0; i < 6; ++i) + assertEquals(6.0 - i, f64_array[i]); +} + +testFloat64x2LoadAndStore(); +testFloat64x2LoadAndStore(); +%OptimizeFunctionOnNextCall(testFloat64x2LoadAndStore); +testFloat64x2LoadAndStore(); + +function testInt32x4LoadAndStore() { + var i32_array = new Int32Array(12); + for (var i = 0; i < 12; ++i) + i32_array[i] = 1 + i; + + var v1 = SIMD.int32x4.load(i32_array, 0); + var v2 = SIMD.int32x4.load(i32_array, 4); + var v3 = SIMD.int32x4.load(i32_array, 8); + + assertEquals(1, v1.x); + assertEquals(2, v1.y); + assertEquals(3, v1.z); + assertEquals(4, v1.w); + + assertEquals(5, v2.x); + assertEquals(6, v2.y); + assertEquals(7, v2.z); + assertEquals(8, v2.w); + + assertEquals(9, v3.x); + assertEquals(10, v3.y); + assertEquals(11, v3.z); + assertEquals(12, v3.w); + + SIMD.int32x4.store(i32_array, 0, SIMD.int32x4(12, 11, 10, 9)); + SIMD.int32x4.store(i32_array, 4, SIMD.int32x4(8, 7, 6, 5)); + SIMD.int32x4.store(i32_array, 8, SIMD.int32x4(4, 3, 2, 1)); + + for (var i = 0; i < 12; ++i) + assertEquals(12.0 - i, i32_array[i]); +} + +testInt32x4LoadAndStore(); +testInt32x4LoadAndStore(); +%OptimizeFunctionOnNextCall(testInt32x4LoadAndStore); +testInt32x4LoadAndStore(); diff --git a/src/xwalk/DEPS.xwalk b/src/xwalk/DEPS.xwalk index 066189b..4138c57 100644 --- a/src/xwalk/DEPS.xwalk +++ b/src/xwalk/DEPS.xwalk @@ -18,7 +18,7 @@ # ----------------------------------- chromium_crosswalk_rev = 'ea46c0b6279a60b0173a092f0e9f0403a2a047a9' -v8_crosswalk_rev = '5b2efeab77f1cda6d70f98f20b393fe40ea6898a' +v8_crosswalk_rev = '825a59c274c95ce90ceab7234c8fa07ad52f7ae5' ozone_wayland_rev = '6379cd118da098b55a5934ce1a90b377a177ed40' # |blink_crosswalk_rev| specifies the SHA1 hash of the blink-crosswalk commit diff --git a/src/xwalk/VERSION b/src/xwalk/VERSION index 68e2c31..a08e2a4 100644 --- a/src/xwalk/VERSION +++ b/src/xwalk/VERSION @@ -1,4 +1,4 @@ MAJOR=11 MINOR=39 -BUILD=256 +BUILD=258 PATCH=0 diff --git a/src/xwalk/application/common/xwalk_application_common.gypi b/src/xwalk/application/common/xwalk_application_common.gypi index b816d1e..2d65e2b 100644 --- a/src/xwalk/application/common/xwalk_application_common.gypi +++ b/src/xwalk/application/common/xwalk_application_common.gypi @@ -6,14 +6,12 @@ 'dependencies': [ '../../../base/base.gyp:base', '../../../base/base.gyp:base_i18n', - '../../../base/base.gyp:xdg_mime', '../../../content/content.gyp:content_common', '../../../crypto/crypto.gyp:crypto', '../../../net/net.gyp:net', '../../../sql/sql.gyp:sql', '../../../url/url.gyp:url_lib', '../../../third_party/libxml/libxml.gyp:libxml', - '../../../third_party/re2/re2.gyp:re2', '../../../third_party/zlib/google/zip.gyp:zip', ], 'sources': [ @@ -55,19 +53,13 @@ 'conditions': [ ['tizen==1', { 'dependencies': [ + '../../../base/base.gyp:xdg_mime', '../../build/system.gyp:tizen', + '../../build/system.gyp:xmlsec', '../../tizen/xwalk_tizen.gypi:xwalk_tizen_lib', '../../../third_party/re2/re2.gyp:re2', '../../../net/net.gyp:net', ], - 'cflags': [ - 'Install(path, &app_id); - if (!success && storage->Contains(app_id)) { + if (!success && !app_id.empty() && storage->Contains(app_id)) { g_print("trying to update %s\n", app_id.c_str()); success = installer->Update(app_id, path); } diff --git a/src/xwalk/application/tools/tizen/xwalk_package_installer.cc b/src/xwalk/application/tools/tizen/xwalk_package_installer.cc index c095fa5..521bfc0 100644 --- a/src/xwalk/application/tools/tizen/xwalk_package_installer.cc +++ b/src/xwalk/application/tools/tizen/xwalk_package_installer.cc @@ -645,7 +645,7 @@ bool PackageInstaller::Uninstall(const std::string& id) { std::string app_id = PrepareUninstallationID(id); if (!xwalk::application::IsValidApplicationID(app_id)) { - LOG(ERROR) << "The given application id " << app_id << " is invalid."; + LOG(ERROR) << "The given application id '" << app_id << "' is invalid."; return false; } @@ -673,8 +673,12 @@ bool PackageInstaller::Uninstall(const std::string& id) { } bool PackageInstaller::Reinstall(const std::string& pkgid) { - base::FilePath app_dir = xwalk::application::GetPackagePath(pkgid); + if (!xwalk::application::IsValidPkgID(pkgid)) { + LOG(ERROR) << "The given package id '" << pkgid << "' is invalid."; + return false; + } + base::FilePath app_dir = xwalk::application::GetPackagePath(pkgid); if (!base::DirectoryExists(app_dir)) { LOG(ERROR) << "Application directory " << app_dir.value() << " does not exist!"; diff --git a/src/xwalk/application/xwalk_application.gypi b/src/xwalk/application/xwalk_application.gypi index b8a7be0..ffa06b7 100644 --- a/src/xwalk/application/xwalk_application.gypi +++ b/src/xwalk/application/xwalk_application.gypi @@ -60,7 +60,6 @@ 'dependencies': [ 'build/system.gyp:tizen', 'tizen/xwalk_tizen.gypi:xwalk_tizen_lib', - '../third_party/re2/re2.gyp:re2', '<(DEPTH)/ui/events/platform/events_platform.gyp:events_platform', ], 'sources': [ diff --git a/src/xwalk/build/system.gyp b/src/xwalk/build/system.gyp index 23dfc03..3886421 100644 --- a/src/xwalk/build/system.gyp +++ b/src/xwalk/build/system.gyp @@ -193,6 +193,23 @@ ], }, }, + { + 'target_name': 'xmlsec', + 'type': 'none', + 'direct_dependent_settings': { + 'cflags': [ + 'web_contents(); - window_ = CreateWindow(runtime_, window_params_); + window_ = RuntimeCreateWindow(runtime_, window_params_); } window_->Show(); #else diff --git a/src/xwalk/runtime/browser/xwalk_browser_context.cc b/src/xwalk/runtime/browser/xwalk_browser_context.cc index 892b11b..19c245c 100644 --- a/src/xwalk/runtime/browser/xwalk_browser_context.cc +++ b/src/xwalk/runtime/browser/xwalk_browser_context.cc @@ -203,7 +203,11 @@ XWalkBrowserContext::GetURLRequestContextGetterById( const std::string& pkg_id) { for (PartitionPathContextGetterMap::iterator it = context_getters_.begin(); it != context_getters_.end(); ++it) { +#if defined(OS_WIN) + if (it->first.find(base::UTF8ToWide(pkg_id))) +#else if (it->first.find(pkg_id)) +#endif return it->second.get(); } return 0; -- 2.7.4