mozilla-bmo1375074.patch
branchfirefox60
changeset 1090 554cd9503f75
parent 1052 7a49806c8dae
child 1091 cbed5671ff47
equal deleted inserted replaced
1080:e8d4a33582b8 1090:554cd9503f75
     1 
     1 
     2 # HG changeset patch
     2 # HG changeset patch
     3 # User Lars T Hansen <lhansen@mozilla.com>
     3 # User Lars T Hansen <lhansen@mozilla.com>
     4 # Date 1519822672 -3600
     4 # Date 1519822672 -3600
     5 # Node ID 800abe66894d6b07b24bccecbf6a65e2261076f6
     5 # Node ID 800abe66894d6b07b24bccecbf6a65e2261076f6
     6 # Parent  223c97459e96183eb616aed39147207bdb953ba8
     6 # Parent  13ecd3214b18e4cab73c54e12e16071d58bed11e
     7 Bug 1375074 - Save and restore non-volatile x28 on ARM64 for generated unboxed object constructor.  r=sstangl
     7 Bug 1375074 - Save and restore non-volatile x28 on ARM64 for generated unboxed object constructor.  r=sstangl
     8 
     8 
     9 diff --git a/js/src/jit-test/tests/bug1375074.js b/js/src/jit-test/tests/bug1375074.js
     9 diff --git a/js/src/jit-test/tests/bug1375074.js b/js/src/jit-test/tests/bug1375074.js
    10 new file mode 100644
    10 new file mode 100644
    11 --- /dev/null
    11 --- /dev/null
    30 +    assertEq(v[i].i, i);
    30 +    assertEq(v[i].i, i);
    31 +}
    31 +}
    32 diff --git a/js/src/vm/UnboxedObject.cpp b/js/src/vm/UnboxedObject.cpp
    32 diff --git a/js/src/vm/UnboxedObject.cpp b/js/src/vm/UnboxedObject.cpp
    33 --- a/js/src/vm/UnboxedObject.cpp
    33 --- a/js/src/vm/UnboxedObject.cpp
    34 +++ b/js/src/vm/UnboxedObject.cpp
    34 +++ b/js/src/vm/UnboxedObject.cpp
    35 @@ -90,17 +90,25 @@ UnboxedLayout::makeConstructorCode(JSCon
    35 @@ -81,18 +81,25 @@ static const uintptr_t CLEAR_CONSTRUCTOR
    36      masm.loadPtr(Address(masm.getStackPointer(), sizeof(void*)), propertiesReg);
    36    masm.loadPtr(Address(masm.getStackPointer(), sizeof(void*)), propertiesReg);
    37      masm.loadPtr(Address(masm.getStackPointer(), 2 * sizeof(void*)), newKindReg);
    37    masm.loadPtr(Address(masm.getStackPointer(), 2 * sizeof(void*)), newKindReg);
    38  #else
    38  #else
    39      propertiesReg = IntArgReg0;
    39    propertiesReg = IntArgReg0;
    40      newKindReg = IntArgReg1;
    40    newKindReg = IntArgReg1;
    41  #endif
    41  #endif
    42  
    42  
    43  #ifdef JS_CODEGEN_ARM64
    43  #ifdef JS_CODEGEN_ARM64
    44 -    // ARM64 communicates stack address via sp, but uses a pseudo-sp for addressing.
    44 -  // ARM64 communicates stack address via sp, but uses a pseudo-sp for
    45 +    // ARM64 communicates stack address via sp, but uses a pseudo-sp (PSP) for
    45 -  // addressing.
    46 +    // addressing.  The register we use for PSP may however also be used by
    46 +  // ARM64 communicates stack address via sp, but uses a pseudo-sp (PSP) for
    47 +    // calling code, and it is nonvolatile, so save it.  Do this as a special
    47 +  // addressing.  The register we use for PSP may however also be used by
    48 +    // case first because the generic save/restore code needs the PSP to be
    48 +  // calling code, and it is nonvolatile, so save it.  Do this as a special
    49 +    // initialized already.
    49 +  // case first because the generic save/restore code needs the PSP to be
    50 +    MOZ_ASSERT(PseudoStackPointer64.Is(masm.GetStackPointer64()));
    50 +  // initialized already.
    51 +    masm.Str(PseudoStackPointer64, vixl::MemOperand(sp, -16, vixl::PreIndex));
    51 +  MOZ_ASSERT(PseudoStackPointer64.Is(masm.GetStackPointer64()));
       
    52 +  masm.Str(PseudoStackPointer64, vixl::MemOperand(sp, -16, vixl::PreIndex));
    52 +
    53 +
    53 +    // Initialize the PSP from the SP.
    54 +  // Initialize the PSP from the SP.
    54      masm.initStackPtr();
    55    masm.initStackPtr();
    55  #endif
    56  #endif
    56  
    57  
    57      MOZ_ASSERT(propertiesReg.volatile_());
    58    MOZ_ASSERT(propertiesReg.volatile_());
    58      MOZ_ASSERT(newKindReg.volatile_());
    59    MOZ_ASSERT(newKindReg.volatile_());
    59  
    60  
    60      AllocatableGeneralRegisterSet regs(GeneralRegisterSet::All());
    61    AllocatableGeneralRegisterSet regs(GeneralRegisterSet::All());
    61      regs.take(propertiesReg);
    62    regs.take(propertiesReg);
    62 @@ -228,17 +236,32 @@ UnboxedLayout::makeConstructorCode(JSCon
    63 @@ -234,17 +241,32 @@ static const uintptr_t CLEAR_CONSTRUCTOR
    63      if (object != ReturnReg)
    64    masm.bind(&done);
    64          masm.movePtr(object, ReturnReg);
       
    65  
    65  
    66      // Restore non-volatile registers which were saved on entry.
    66    if (object != ReturnReg) masm.movePtr(object, ReturnReg);
    67      if (ScratchDoubleReg.volatile_())
    67  
    68          masm.pop(ScratchDoubleReg);
    68    // Restore non-volatile registers which were saved on entry.
    69      masm.PopRegsInMask(savedNonVolatileRegisters);
    69    if (ScratchDoubleReg.volatile_()) masm.pop(ScratchDoubleReg);
       
    70    masm.PopRegsInMask(savedNonVolatileRegisters);
    70  
    71  
    71 +#ifdef JS_CODEGEN_ARM64
    72 +#ifdef JS_CODEGEN_ARM64
    72 +    // Now restore the value that was in the PSP register on entry, and return.
    73 +  // Now restore the value that was in the PSP register on entry, and return.
    73 +
    74 +
    74 +    // Obtain the correct SP from the PSP.
    75 +  // Obtain the correct SP from the PSP.
    75 +    masm.Mov(sp, PseudoStackPointer64);
    76 +  masm.Mov(sp, PseudoStackPointer64);
    76 +
    77 +
    77 +    // Restore the saved value of the PSP register, this value is whatever the
    78 +  // Restore the saved value of the PSP register, this value is whatever the
    78 +    // caller had saved in it, not any actual SP value, and it must not be
    79 +  // caller had saved in it, not any actual SP value, and it must not be
    79 +    // overwritten subsequently.
    80 +  // overwritten subsequently.
    80 +    masm.Ldr(PseudoStackPointer64, vixl::MemOperand(sp, 16, vixl::PostIndex));
    81 +  masm.Ldr(PseudoStackPointer64, vixl::MemOperand(sp, 16, vixl::PostIndex));
    81 +
    82 +
    82 +    // Perform a plain Ret(), as abiret() will move SP <- PSP and that is wrong.
    83 +  // Perform a plain Ret(), as abiret() will move SP <- PSP and that is wrong.
    83 +    masm.Ret(vixl::lr);
    84 +  masm.Ret(vixl::lr);
    84 +#else
    85 +#else
    85      masm.abiret();
    86    masm.abiret();
    86 +#endif
    87 +#endif
    87  
    88  
    88      masm.bind(&failureStoreOther);
    89    masm.bind(&failureStoreOther);
    89  
    90  
    90      // There was a failure while storing a value which cannot be stored at all
    91    // There was a failure while storing a value which cannot be stored at all
    91      // in the unboxed object. Initialize the object so it is safe for GC and
    92    // in the unboxed object. Initialize the object so it is safe for GC and
    92      // return null.
    93    // return null.
    93      masm.initUnboxedObjectContents(object, templateObject);
    94    masm.initUnboxedObjectContents(object, templateObject);
    94  
    95  
    95