Title: [229842] trunk
Revision
229842
Author
[email protected]
Date
2018-03-21 19:15:44 -0700 (Wed, 21 Mar 2018)

Log Message

ScopedArguments should do poisoning and index masking
https://bugs.webkit.org/show_bug.cgi?id=183863

Reviewed by Mark Lam.
        
JSTests:

Adds another stress test of scoped arguments.

* stress/scoped-arguments-test.js: Added.
(foo):

Source/_javascript_Core:

This outlines the ScopedArguments overflow storage and adds poisoning.

* bytecode/AccessCase.cpp:
(JSC::AccessCase::generateWithGuard):
* dfg/DFGSpeculativeJIT.cpp:
(JSC::DFG::SpeculativeJIT::compileGetByValOnScopedArguments):
(JSC::DFG::SpeculativeJIT::compileGetArrayLength):
* ftl/FTLAbstractHeapRepository.h:
* ftl/FTLLowerDFGToB3.cpp:
(JSC::FTL::DFG::LowerDFGToB3::compileGetArrayLength):
(JSC::FTL::DFG::LowerDFGToB3::compileGetByVal):
* jit/JITPropertyAccess.cpp:
(JSC::JIT::emitScopedArgumentsGetByVal):
* runtime/JSCPoison.h:
* runtime/ScopedArguments.cpp:
(JSC::ScopedArguments::ScopedArguments):
(JSC::ScopedArguments::createUninitialized):
(JSC::ScopedArguments::visitChildren):
* runtime/ScopedArguments.h:

Modified Paths

Added Paths

Diff

Modified: trunk/JSTests/ChangeLog (229841 => 229842)


--- trunk/JSTests/ChangeLog	2018-03-22 01:49:27 UTC (rev 229841)
+++ trunk/JSTests/ChangeLog	2018-03-22 02:15:44 UTC (rev 229842)
@@ -1,3 +1,15 @@
+2018-03-21  Filip Pizlo  <[email protected]>
+
+        ScopedArguments should do poisoning and index masking
+        https://bugs.webkit.org/show_bug.cgi?id=183863
+
+        Reviewed by Mark Lam.
+        
+        Adds another stress test of scoped arguments.
+
+        * stress/scoped-arguments-test.js: Added.
+        (foo):
+
 2018-03-20  Saam Barati  <[email protected]>
 
         We need to do proper bookkeeping of exitOK when inserting constants when sinking NewArrayBuffer

Added: trunk/JSTests/stress/scoped-arguments-test.js (0 => 229842)


--- trunk/JSTests/stress/scoped-arguments-test.js	                        (rev 0)
+++ trunk/JSTests/stress/scoped-arguments-test.js	2018-03-22 02:15:44 UTC (rev 229842)
@@ -0,0 +1,16 @@
+function foo(a)
+{
+    (function() { return a; })();
+    return [arguments[0], arguments];
+}
+
+noInline(foo);
+
+for (var i = 0; i < 10000; ++i) {
+    var result = foo(42);
+    if (result[0] != 42)
+        throw new Error("result[0] is not 42: " + result[0]);
+    if (result[1][0] != 42)
+        throw new Error("result[1][0] is not 42: " + result[1][0]);
+}
+

Modified: trunk/Source/_javascript_Core/ChangeLog (229841 => 229842)


--- trunk/Source/_javascript_Core/ChangeLog	2018-03-22 01:49:27 UTC (rev 229841)
+++ trunk/Source/_javascript_Core/ChangeLog	2018-03-22 02:15:44 UTC (rev 229842)
@@ -1,3 +1,30 @@
+2018-03-21  Filip Pizlo  <[email protected]>
+
+        ScopedArguments should do poisoning and index masking
+        https://bugs.webkit.org/show_bug.cgi?id=183863
+
+        Reviewed by Mark Lam.
+        
+        This outlines the ScopedArguments overflow storage and adds poisoning.
+
+        * bytecode/AccessCase.cpp:
+        (JSC::AccessCase::generateWithGuard):
+        * dfg/DFGSpeculativeJIT.cpp:
+        (JSC::DFG::SpeculativeJIT::compileGetByValOnScopedArguments):
+        (JSC::DFG::SpeculativeJIT::compileGetArrayLength):
+        * ftl/FTLAbstractHeapRepository.h:
+        * ftl/FTLLowerDFGToB3.cpp:
+        (JSC::FTL::DFG::LowerDFGToB3::compileGetArrayLength):
+        (JSC::FTL::DFG::LowerDFGToB3::compileGetByVal):
+        * jit/JITPropertyAccess.cpp:
+        (JSC::JIT::emitScopedArgumentsGetByVal):
+        * runtime/JSCPoison.h:
+        * runtime/ScopedArguments.cpp:
+        (JSC::ScopedArguments::ScopedArguments):
+        (JSC::ScopedArguments::createUninitialized):
+        (JSC::ScopedArguments::visitChildren):
+        * runtime/ScopedArguments.h:
+
 2018-03-21  Mark Lam  <[email protected]>
 
         Refactor the PtrTag list as a macro so that we can auto-generate code that enumerates each PtrTag.

Modified: trunk/Source/_javascript_Core/bytecode/AccessCase.cpp (229841 => 229842)


--- trunk/Source/_javascript_Core/bytecode/AccessCase.cpp	2018-03-22 01:49:27 UTC (rev 229841)
+++ trunk/Source/_javascript_Core/bytecode/AccessCase.cpp	2018-03-22 02:15:44 UTC (rev 229842)
@@ -403,12 +403,16 @@
                 CCallHelpers::Address(baseGPR, JSCell::typeInfoTypeOffset()),
                 CCallHelpers::TrustedImm32(ScopedArgumentsType)));
 
+        jit.loadPtr(
+            CCallHelpers::Address(baseGPR, ScopedArguments::offsetOfStorage()),
+            scratchGPR);
+        jit.xorPtr(CCallHelpers::TrustedImmPtr(ScopedArgumentsPoison::key()), scratchGPR);
         fallThrough.append(
             jit.branchTest8(
                 CCallHelpers::NonZero,
-                CCallHelpers::Address(baseGPR, ScopedArguments::offsetOfOverrodeThings())));
+                CCallHelpers::Address(scratchGPR, ScopedArguments::offsetOfOverrodeThingsInStorage())));
         jit.load32(
-            CCallHelpers::Address(baseGPR, ScopedArguments::offsetOfTotalLength()),
+            CCallHelpers::Address(scratchGPR, ScopedArguments::offsetOfTotalLengthInStorage()),
             valueRegs.payloadGPR());
         jit.boxInt32(valueRegs.payloadGPR(), valueRegs);
         state.succeed();

Modified: trunk/Source/_javascript_Core/dfg/DFGArrayMode.cpp (229841 => 229842)


--- trunk/Source/_javascript_Core/dfg/DFGArrayMode.cpp	2018-03-22 01:49:27 UTC (rev 229841)
+++ trunk/Source/_javascript_Core/dfg/DFGArrayMode.cpp	2018-03-22 02:15:44 UTC (rev 229842)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2012-2017 Apple Inc. All rights reserved.
+ * Copyright (C) 2012-2018 Apple Inc. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -271,6 +271,8 @@
                     return ArrayMode(type, Array::NonArray, Array::OutOfBounds, Array::AsIs);
                 return ArrayMode(Array::Generic);
             }
+            if (isX86() && is32Bit() && isScopedArgumentsSpeculation(base))
+                return ArrayMode(Array::Generic);
             return withType(type);
         }
         

Modified: trunk/Source/_javascript_Core/dfg/DFGOSRExit.cpp (229841 => 229842)


--- trunk/Source/_javascript_Core/dfg/DFGOSRExit.cpp	2018-03-22 01:49:27 UTC (rev 229841)
+++ trunk/Source/_javascript_Core/dfg/DFGOSRExit.cpp	2018-03-22 02:15:44 UTC (rev 229842)
@@ -217,7 +217,7 @@
     DirectArguments* result = DirectArguments::create(
         vm, codeBlock->globalObject()->directArgumentsStructure(), length, capacity);
 
-    result->callee().set(vm, result, callee);
+    result->setCallee(vm, callee);
 
     void* frameBase = context.fp<Register*>() + (inlineCallFrame ? inlineCallFrame->stackOffset : 0);
     Frame frame(frameBase, context.stack());

Modified: trunk/Source/_javascript_Core/dfg/DFGOperations.cpp (229841 => 229842)


--- trunk/Source/_javascript_Core/dfg/DFGOperations.cpp	2018-03-22 01:49:27 UTC (rev 229841)
+++ trunk/Source/_javascript_Core/dfg/DFGOperations.cpp	2018-03-22 02:15:44 UTC (rev 229842)
@@ -1701,7 +1701,7 @@
     DirectArguments* result = DirectArguments::create(
         vm, codeBlock->globalObject()->directArgumentsStructure(), length, capacity);
     
-    result->callee().set(vm, result, callee);
+    result->setCallee(vm, callee);
     
     Register* arguments =
         exec->registers() + (inlineCallFrame ? inlineCallFrame->stackOffset : 0) +

Modified: trunk/Source/_javascript_Core/dfg/DFGSpeculativeJIT.cpp (229841 => 229842)


--- trunk/Source/_javascript_Core/dfg/DFGSpeculativeJIT.cpp	2018-03-22 01:49:27 UTC (rev 229841)
+++ trunk/Source/_javascript_Core/dfg/DFGSpeculativeJIT.cpp	2018-03-22 02:15:44 UTC (rev 229842)
@@ -6488,6 +6488,7 @@
 #endif
     GPRTemporary scratch(this);
     GPRTemporary scratch2(this);
+    GPRTemporary indexMask(this);
     
     GPRReg baseReg = base.gpr();
     GPRReg propertyReg = property.gpr();
@@ -6500,6 +6501,7 @@
 #endif
     GPRReg scratchReg = scratch.gpr();
     GPRReg scratch2Reg = scratch2.gpr();
+    GPRReg indexMaskReg = indexMask.gpr();
     
     if (!m_compileOkay)
         return;
@@ -6506,13 +6508,22 @@
     
     ASSERT(ArrayMode(Array::ScopedArguments).alreadyChecked(m_jit.graph(), node, m_state.forNode(m_graph.varArgChild(node, 0))));
     
+    m_jit.loadPtr(
+        MacroAssembler::Address(baseReg, ScopedArguments::offsetOfStorage()), resultReg);
+    m_jit.xorPtr(TrustedImmPtr(ScopedArgumentsPoison::key()), resultReg);
+    
+    m_jit.load32(
+        MacroAssembler::Address(resultReg, ScopedArguments::offsetOfTotalLengthInStorage()),
+        scratchReg);
+    
     speculationCheck(
         ExoticObjectMode, JSValueSource(), nullptr,
-        m_jit.branch32(
-            MacroAssembler::AboveOrEqual, propertyReg,
-            MacroAssembler::Address(baseReg, ScopedArguments::offsetOfTotalLength())));
+        m_jit.branch32(MacroAssembler::AboveOrEqual, propertyReg, scratchReg));
     
+    m_jit.emitPreparePreciseIndexMask32(propertyReg, scratchReg, indexMaskReg);
+    
     m_jit.loadPtr(MacroAssembler::Address(baseReg, ScopedArguments::offsetOfTable()), scratchReg);
+    m_jit.xorPtr(TrustedImmPtr(ScopedArgumentsPoison::key()), scratchReg);
     m_jit.load32(
         MacroAssembler::Address(scratchReg, ScopedArgumentsTable::offsetOfLength()), scratch2Reg);
     
@@ -6520,6 +6531,7 @@
         MacroAssembler::AboveOrEqual, propertyReg, scratch2Reg);
     
     m_jit.loadPtr(MacroAssembler::Address(baseReg, ScopedArguments::offsetOfScope()), scratch2Reg);
+    m_jit.xorPtr(TrustedImmPtr(ScopedArgumentsPoison::key()), scratch2Reg);
 
     m_jit.loadPtr(
         MacroAssembler::Address(scratchReg, ScopedArgumentsTable::offsetOfArguments()),
@@ -6547,13 +6559,14 @@
     
     m_jit.loadValue(
         MacroAssembler::BaseIndex(
-            baseReg, scratch2Reg, MacroAssembler::TimesEight,
-            ScopedArguments::overflowStorageOffset()),
+            resultReg, scratch2Reg, MacroAssembler::TimesEight),
         resultRegs);
     speculationCheck(ExoticObjectMode, JSValueSource(), nullptr, m_jit.branchIfEmpty(resultRegs));
     
     done.link(&m_jit);
     
+    m_jit.andPtr(indexMaskReg, resultReg);
+    
     jsValueResult(resultRegs, node);
 }
 
@@ -6650,8 +6663,7 @@
         
         m_jit.loadPtr(
             MacroAssembler::Address(baseReg, DirectArguments::offsetOfStorage()), resultReg);
-        m_jit.xorPtr(
-            TrustedImmPtr(DirectArgumentsPoison::key()), resultReg);
+        m_jit.xorPtr(TrustedImmPtr(DirectArgumentsPoison::key()), resultReg);
         m_jit.load32(
             MacroAssembler::Address(resultReg, DirectArguments::offsetOfLengthInStorage()), resultReg);
         
@@ -6660,7 +6672,7 @@
     }
     case Array::ScopedArguments: {
         SpeculateCellOperand base(this, node->child1());
-        GPRTemporary result(this, Reuse, base);
+        GPRTemporary result(this);
         
         GPRReg baseReg = base.gpr();
         GPRReg resultReg = result.gpr();
@@ -6670,14 +6682,18 @@
         
         ASSERT(ArrayMode(Array::ScopedArguments).alreadyChecked(m_jit.graph(), node, m_state.forNode(node->child1())));
         
+        m_jit.loadPtr(
+            MacroAssembler::Address(baseReg, ScopedArguments::offsetOfStorage()), resultReg);
+        m_jit.xorPtr(TrustedImmPtr(ScopedArgumentsPoison::key()), resultReg);
+        
         speculationCheck(
             ExoticObjectMode, JSValueSource(), 0,
             m_jit.branchTest8(
                 MacroAssembler::NonZero,
-                MacroAssembler::Address(baseReg, ScopedArguments::offsetOfOverrodeThings())));
+                MacroAssembler::Address(resultReg, ScopedArguments::offsetOfOverrodeThingsInStorage())));
         
         m_jit.load32(
-            MacroAssembler::Address(baseReg, ScopedArguments::offsetOfTotalLength()), resultReg);
+            MacroAssembler::Address(resultReg, ScopedArguments::offsetOfTotalLengthInStorage()), resultReg);
         
         int32Result(resultReg, node);
         break;

Modified: trunk/Source/_javascript_Core/ftl/FTLAbstractHeapRepository.h (229841 => 229842)


--- trunk/Source/_javascript_Core/ftl/FTLAbstractHeapRepository.h	2018-03-22 01:49:27 UTC (rev 229841)
+++ trunk/Source/_javascript_Core/ftl/FTLAbstractHeapRepository.h	2018-03-22 02:15:44 UTC (rev 229842)
@@ -102,10 +102,11 @@
     macro(ShadowChicken_Packet_scope, OBJECT_OFFSETOF(ShadowChicken::Packet, scope)) \
     macro(ShadowChicken_Packet_codeBlock, OBJECT_OFFSETOF(ShadowChicken::Packet, codeBlock)) \
     macro(ShadowChicken_Packet_callSiteIndex, OBJECT_OFFSETOF(ShadowChicken::Packet, callSiteIndex)) \
-    macro(ScopedArguments_overrodeThings, ScopedArguments::offsetOfOverrodeThings()) \
+    macro(ScopedArguments_Storage_overrodeThings, ScopedArguments::offsetOfOverrodeThingsInStorage()) \
+    macro(ScopedArguments_Storage_totalLength, ScopedArguments::offsetOfTotalLengthInStorage()) \
+    macro(ScopedArguments_storage, ScopedArguments::offsetOfStorage()) \
     macro(ScopedArguments_scope, ScopedArguments::offsetOfScope()) \
     macro(ScopedArguments_table, ScopedArguments::offsetOfTable()) \
-    macro(ScopedArguments_totalLength, ScopedArguments::offsetOfTotalLength()) \
     macro(ScopedArgumentsTable_arguments, ScopedArgumentsTable::offsetOfArguments()) \
     macro(ScopedArgumentsTable_length, ScopedArgumentsTable::offsetOfLength()) \
     macro(StringImpl_data, StringImpl::dataOffset()) \
@@ -138,7 +139,7 @@
     macro(JSLexicalEnvironment_variables, JSLexicalEnvironment::offsetOfVariables(), sizeof(EncodedJSValue)) \
     macro(JSPropertyNameEnumerator_cachedPropertyNamesVectorContents, 0, sizeof(WriteBarrier<JSString>)) \
     macro(JSRopeString_fibers, JSRopeString::offsetOfFibers(), sizeof(WriteBarrier<JSString>)) \
-    macro(ScopedArguments_overflowStorage, ScopedArguments::overflowStorageOffset(), sizeof(EncodedJSValue)) \
+    macro(ScopedArguments_Storage_storage, 0, sizeof(EncodedJSValue)) \
     macro(WriteBarrierBuffer_bufferContents, 0, sizeof(JSCell*)) \
     macro(characters8, 0, sizeof(LChar)) \
     macro(characters16, 0, sizeof(UChar)) \

Modified: trunk/Source/_javascript_Core/ftl/FTLLowerDFGToB3.cpp (229841 => 229842)


--- trunk/Source/_javascript_Core/ftl/FTLLowerDFGToB3.cpp	2018-03-22 01:49:27 UTC (rev 229841)
+++ trunk/Source/_javascript_Core/ftl/FTLLowerDFGToB3.cpp	2018-03-22 02:15:44 UTC (rev 229842)
@@ -3682,10 +3682,13 @@
             
         case Array::ScopedArguments: {
             LValue arguments = lowCell(m_node->child1());
+            LValue storage = m_out.bitXor(
+                m_out.loadPtr(arguments, m_heaps.ScopedArguments_storage),
+                m_out.constIntPtr(ScopedArgumentsPoison::key()));
             speculate(
                 ExoticObjectMode, noValue(), nullptr,
-                m_out.notZero32(m_out.load8ZeroExt32(arguments, m_heaps.ScopedArguments_overrodeThings)));
-            setInt32(m_out.load32NonNegative(arguments, m_heaps.ScopedArguments_totalLength));
+                m_out.notZero32(m_out.load8ZeroExt32(storage, m_heaps.ScopedArguments_Storage_overrodeThings)));
+            setInt32(m_out.load32NonNegative(storage, m_heaps.ScopedArguments_Storage_totalLength));
             return;
         }
             
@@ -3883,13 +3886,18 @@
             LValue base = lowCell(m_graph.varArgChild(m_node, 0));
             LValue index = lowInt32(m_graph.varArgChild(m_node, 1));
             
+            LValue storage = m_out.loadPtr(base, m_heaps.ScopedArguments_storage);
+            storage = m_out.bitXor(storage, m_out.constIntPtr(ScopedArgumentsPoison::key()));
+            
+            LValue totalLength = m_out.load32NonNegative(
+                storage, m_heaps.ScopedArguments_Storage_totalLength);
             speculate(
                 ExoticObjectMode, noValue(), nullptr,
-                m_out.aboveOrEqual(
-                    index,
-                    m_out.load32NonNegative(base, m_heaps.ScopedArguments_totalLength)));
+                m_out.aboveOrEqual(index, totalLength));
             
             LValue table = m_out.loadPtr(base, m_heaps.ScopedArguments_table);
+            table = m_out.bitXor(table, m_out.constIntPtr(ScopedArgumentsPoison::key()));
+            
             LValue namedLength = m_out.load32(table, m_heaps.ScopedArgumentsTable_length);
             
             LBasicBlock namedCase = m_out.newBlock();
@@ -3902,6 +3910,8 @@
             LBasicBlock lastNext = m_out.appendTo(namedCase, overflowCase);
             
             LValue scope = m_out.loadPtr(base, m_heaps.ScopedArguments_scope);
+            scope = m_out.bitXor(scope, m_out.constIntPtr(ScopedArgumentsPoison::key()));
+            
             LValue arguments = m_out.loadPtr(table, m_heaps.ScopedArgumentsTable_arguments);
             
             TypedPointer address = m_out.baseIndex(
@@ -3920,7 +3930,7 @@
             m_out.appendTo(overflowCase, continuation);
             
             address = m_out.baseIndex(
-                m_heaps.ScopedArguments_overflowStorage, base,
+                m_heaps.ScopedArguments_Storage_storage, storage,
                 m_out.zeroExtPtr(m_out.sub(index, namedLength)));
             LValue overflowValue = m_out.load64(address);
             speculate(ExoticObjectMode, noValue(), nullptr, m_out.isZero64(overflowValue));
@@ -3928,7 +3938,11 @@
             m_out.jump(continuation);
             
             m_out.appendTo(continuation, lastNext);
-            setJSValue(m_out.phi(Int64, namedResult, overflowResult));
+            
+            LValue result = m_out.phi(Int64, namedResult, overflowResult);
+            result = preciseIndexMask32(result, index, totalLength);
+            
+            setJSValue(result);
             return;
         }
             

Modified: trunk/Source/_javascript_Core/ftl/FTLOperations.cpp (229841 => 229842)


--- trunk/Source/_javascript_Core/ftl/FTLOperations.cpp	2018-03-22 01:49:27 UTC (rev 229841)
+++ trunk/Source/_javascript_Core/ftl/FTLOperations.cpp	2018-03-22 02:15:44 UTC (rev 229842)
@@ -336,7 +336,7 @@
             unsigned capacity = std::max(length, static_cast<unsigned>(codeBlock->numParameters() - 1));
             DirectArguments* result = DirectArguments::create(
                 vm, codeBlock->globalObject()->directArgumentsStructure(), length, capacity);
-            result->callee().set(vm, result, callee);
+            result->setCallee(vm, callee);
             for (unsigned i = materialization->properties().size(); i--;) {
                 const ExitPropertyValue& property = materialization->properties()[i];
                 if (property.location().kind() != ArgumentPLoc)

Modified: trunk/Source/_javascript_Core/jit/JITPropertyAccess.cpp (229841 => 229842)


--- trunk/Source/_javascript_Core/jit/JITPropertyAccess.cpp	2018-03-22 01:49:27 UTC (rev 229841)
+++ trunk/Source/_javascript_Core/jit/JITPropertyAccess.cpp	2018-03-22 02:15:44 UTC (rev 229842)
@@ -1441,6 +1441,7 @@
     JSValueRegs result = JSValueRegs(regT0);
     RegisterID scratch = regT3;
     RegisterID scratch2 = regT4;
+    RegisterID scratch3 = regT5;
 #else
     RegisterID base = regT0;
     RegisterID property = regT2;
@@ -1447,16 +1448,21 @@
     JSValueRegs result = JSValueRegs(regT1, regT0);
     RegisterID scratch = regT3;
     RegisterID scratch2 = regT4;
+    RegisterID scratch3 = regT5;
 #endif
 
     load8(Address(base, JSCell::typeInfoTypeOffset()), scratch);
     badType = patchableBranch32(NotEqual, scratch, TrustedImm32(ScopedArgumentsType));
-    slowCases.append(branch32(AboveOrEqual, property, Address(base, ScopedArguments::offsetOfTotalLength())));
+    loadPtr(Address(base, ScopedArguments::offsetOfStorage()), scratch3);
+    xorPtr(TrustedImmPtr(ScopedArgumentsPoison::key()), scratch3);
+    slowCases.append(branch32(AboveOrEqual, property, Address(scratch3, ScopedArguments::offsetOfTotalLengthInStorage())));
     
     loadPtr(Address(base, ScopedArguments::offsetOfTable()), scratch);
+    xorPtr(TrustedImmPtr(ScopedArgumentsPoison::key()), scratch);
     load32(Address(scratch, ScopedArgumentsTable::offsetOfLength()), scratch2);
     Jump overflowCase = branch32(AboveOrEqual, property, scratch2);
     loadPtr(Address(base, ScopedArguments::offsetOfScope()), scratch2);
+    xorPtr(TrustedImmPtr(ScopedArgumentsPoison::key()), scratch2);
     loadPtr(Address(scratch, ScopedArgumentsTable::offsetOfArguments()), scratch);
     load32(BaseIndex(scratch, property, TimesFour), scratch);
     slowCases.append(branch32(Equal, scratch, TrustedImm32(ScopeOffset::invalidOffset)));
@@ -1465,10 +1471,14 @@
     overflowCase.link(this);
     sub32(property, scratch2);
     neg32(scratch2);
-    loadValue(BaseIndex(base, scratch2, TimesEight, ScopedArguments::overflowStorageOffset()), result);
+    loadValue(BaseIndex(scratch3, scratch2, TimesEight), result);
     slowCases.append(branchIfEmpty(result));
     done.link(this);
     
+    load32(Address(scratch3, ScopedArguments::offsetOfTotalLengthInStorage()), scratch);
+    emitPreparePreciseIndexMask32(property, scratch, scratch2);
+    andPtr(scratch2, result.payloadGPR());
+    
     return slowCases;
 }
 

Modified: trunk/Source/_javascript_Core/runtime/DirectArguments.cpp (229841 => 229842)


--- trunk/Source/_javascript_Core/runtime/DirectArguments.cpp	2018-03-22 01:49:27 UTC (rev 229841)
+++ trunk/Source/_javascript_Core/runtime/DirectArguments.cpp	2018-03-22 02:15:44 UTC (rev 229842)
@@ -85,7 +85,7 @@
     for (unsigned i = capacity; i--;)
         storage[i].set(vm, result, exec->getArgumentUnsafe(i));
     
-    result->callee().set(vm, result, jsCast<JSFunction*>(exec->jsCallee()));
+    result->setCallee(vm, jsCast<JSFunction*>(exec->jsCallee()));
     
     return result;
 }

Modified: trunk/Source/_javascript_Core/runtime/DirectArguments.h (229841 => 229842)


--- trunk/Source/_javascript_Core/runtime/DirectArguments.h	2018-03-22 01:49:27 UTC (rev 229841)
+++ trunk/Source/_javascript_Core/runtime/DirectArguments.h	2018-03-22 02:15:44 UTC (rev 229842)
@@ -110,11 +110,16 @@
         preciseIndexMaskPtr(i, storageHeader(storage).length, ptr)->set(vm, this, value);
     }
     
-    WriteBarrier<JSFunction>& callee()
+    JSFunction* callee()
     {
-        return m_callee;
+        return m_callee.get();
     }
     
+    void setCallee(VM& vm, JSFunction* function)
+    {
+        m_callee.set(vm, this, function);
+    }
+    
     WriteBarrier<Unknown>& argument(DirectArgumentsOffset offset)
     {
         ASSERT(offset);

Modified: trunk/Source/_javascript_Core/runtime/GenericArgumentsInlines.h (229841 => 229842)


--- trunk/Source/_javascript_Core/runtime/GenericArgumentsInlines.h	2018-03-22 01:49:27 UTC (rev 229841)
+++ trunk/Source/_javascript_Core/runtime/GenericArgumentsInlines.h	2018-03-22 02:15:44 UTC (rev 229842)
@@ -52,7 +52,7 @@
             return true;
         }
         if (ident == vm.propertyNames->callee) {
-            slot.setValue(thisObject, static_cast<unsigned>(PropertyAttribute::DontEnum), thisObject->callee().get());
+            slot.setValue(thisObject, static_cast<unsigned>(PropertyAttribute::DontEnum), thisObject->callee());
             return true;
         }
         if (ident == vm.propertyNames->iteratorSymbol) {

Modified: trunk/Source/_javascript_Core/runtime/JSCPoison.h (229841 => 229842)


--- trunk/Source/_javascript_Core/runtime/JSCPoison.h	2018-03-22 01:49:27 UTC (rev 229841)
+++ trunk/Source/_javascript_Core/runtime/JSCPoison.h	2018-03-22 02:15:44 UTC (rev 229842)
@@ -50,6 +50,7 @@
     v(JSWebAssemblyModule) \
     v(JSWebAssemblyTable) \
     v(NativeCode) \
+    v(ScopedArguments) \
     v(StructureTransitionTable) \
     v(UnlinkedSourceCode) \
     v(WebAssemblyFunctionBase) \

Modified: trunk/Source/_javascript_Core/runtime/ScopedArguments.cpp (229841 => 229842)


--- trunk/Source/_javascript_Core/runtime/ScopedArguments.cpp	2018-03-22 01:49:27 UTC (rev 229841)
+++ trunk/Source/_javascript_Core/runtime/ScopedArguments.cpp	2018-03-22 02:15:44 UTC (rev 229842)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2015 Apple Inc. All rights reserved.
+ * Copyright (C) 2015-2018 Apple Inc. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -35,11 +35,11 @@
 
 const ClassInfo ScopedArguments::s_info = { "Arguments", &Base::s_info, nullptr, nullptr, CREATE_METHOD_TABLE(ScopedArguments) };
 
-ScopedArguments::ScopedArguments(VM& vm, Structure* structure, unsigned totalLength)
+ScopedArguments::ScopedArguments(VM& vm, Structure* structure, WriteBarrier<Unknown>* storage)
     : GenericArguments(vm, structure)
-    , m_overrodeThings(false)
-    , m_totalLength(totalLength)
+    , m_storage(vm, this, storage)
 {
+    ASSERT(!storageHeader(storage).overrodeThings);
 }
 
 void ScopedArguments::finishCreation(VM& vm, JSFunction* callee, ScopedArgumentsTable* table, JSLexicalEnvironment* scope)
@@ -57,10 +57,17 @@
         overflowLength = totalLength - table->length();
     else
         overflowLength = 0;
+    
+    void* rawStoragePtr = vm.jsValueGigacageAuxiliarySpace.allocateNonVirtual(
+        vm, storageSize(overflowLength), nullptr, AllocationFailureMode::Assert);
+    WriteBarrier<Unknown>* storage = static_cast<WriteBarrier<Unknown>*>(rawStoragePtr) + 1;
+    storageHeader(storage).overrodeThings = false;
+    storageHeader(storage).totalLength = totalLength;
+    
     ScopedArguments* result = new (
         NotNull,
-        allocateCell<ScopedArguments>(vm.heap, allocationSize(overflowLength)))
-        ScopedArguments(vm, structure, totalLength);
+        allocateCell<ScopedArguments>(vm.heap))
+        ScopedArguments(vm, structure, storage);
     result->finishCreation(vm, callee, table, scope);
     return result;
 }
@@ -107,9 +114,11 @@
     visitor.append(thisObject->m_table);
     visitor.append(thisObject->m_scope);
     
-    if (thisObject->m_totalLength > thisObject->m_table->length()) {
+    visitor.markAuxiliary(&thisObject->storageHeader());
+    
+    if (thisObject->storageHeader().totalLength > thisObject->m_table->length()) {
         visitor.appendValues(
-            thisObject->overflowStorage(), thisObject->m_totalLength - thisObject->m_table->length());
+            thisObject->overflowStorage(), thisObject->storageHeader().totalLength - thisObject->m_table->length());
     }
 
     GenericArguments<ScopedArguments>::visitChildren(cell, visitor);
@@ -122,24 +131,24 @@
 
 void ScopedArguments::overrideThings(VM& vm)
 {
-    RELEASE_ASSERT(!m_overrodeThings);
+    RELEASE_ASSERT(!storageHeader().overrodeThings);
     
     putDirect(vm, vm.propertyNames->length, jsNumber(m_table->length()), static_cast<unsigned>(PropertyAttribute::DontEnum));
     putDirect(vm, vm.propertyNames->callee, m_callee.get(), static_cast<unsigned>(PropertyAttribute::DontEnum));
     putDirect(vm, vm.propertyNames->iteratorSymbol, globalObject()->arrayProtoValuesFunction(), static_cast<unsigned>(PropertyAttribute::DontEnum));
     
-    m_overrodeThings = true;
+    storageHeader().overrodeThings = true;
 }
 
 void ScopedArguments::overrideThingsIfNecessary(VM& vm)
 {
-    if (!m_overrodeThings)
+    if (!storageHeader().overrodeThings)
         overrideThings(vm);
 }
 
 void ScopedArguments::unmapArgument(VM& vm, uint32_t i)
 {
-    ASSERT_WITH_SECURITY_IMPLICATION(i < m_totalLength);
+    ASSERT_WITH_SECURITY_IMPLICATION(i < storageHeader().totalLength);
     unsigned namedLength = m_table->length();
     if (i < namedLength)
         m_table.set(vm, this, m_table->set(vm, i, ScopeOffset()));

Modified: trunk/Source/_javascript_Core/runtime/ScopedArguments.h (229841 => 229842)


--- trunk/Source/_javascript_Core/runtime/ScopedArguments.h	2018-03-22 01:49:27 UTC (rev 229841)
+++ trunk/Source/_javascript_Core/runtime/ScopedArguments.h	2018-03-22 02:15:44 UTC (rev 229842)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2015-2016 Apple Inc. All rights reserved.
+ * Copyright (C) 2015-2018 Apple Inc. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -38,7 +38,7 @@
 // lookups.
 class ScopedArguments final : public GenericArguments<ScopedArguments> {
 private:
-    ScopedArguments(VM&, Structure*, unsigned totalLength);
+    ScopedArguments(VM&, Structure*, WriteBarrier<Unknown>* storage);
     void finishCreation(VM&, JSFunction* callee, ScopedArgumentsTable*, JSLexicalEnvironment*);
 
 public:
@@ -67,13 +67,13 @@
     
     uint32_t internalLength() const
     {
-        return m_totalLength;
+        return storageHeader().totalLength;
     }
     
     uint32_t length(ExecState* exec) const
     {
         VM& vm = exec->vm();
-        if (UNLIKELY(m_overrodeThings))
+        if (UNLIKELY(storageHeader().overrodeThings))
             return get(exec, vm.propertyNames->length).toUInt32(exec);
         return internalLength();
     }
@@ -80,12 +80,13 @@
     
     bool isMappedArgument(uint32_t i) const
     {
-        if (i >= m_totalLength)
+        WriteBarrier<Unknown>* storage = overflowStorage();
+        if (i >= storageHeader(storage).totalLength)
             return false;
         unsigned namedLength = m_table->length();
         if (i < namedLength)
             return !!m_table->get(i);
-        return !!overflowStorage()[i - namedLength].get();
+        return !!storage[i - namedLength].get();
     }
 
     bool isMappedArgumentInDFG(uint32_t i) const
@@ -96,28 +97,32 @@
     JSValue getIndexQuickly(uint32_t i) const
     {
         ASSERT_WITH_SECURITY_IMPLICATION(isMappedArgument(i));
+        WriteBarrier<Unknown>* storage = overflowStorage();
+        unsigned totalLength = storageHeader(storage).totalLength;
         unsigned namedLength = m_table->length();
         if (i < namedLength)
-            return m_scope->variableAt(m_table->get(i)).get();
-        return overflowStorage()[i - namedLength].get();
+            return preciseIndexMaskPtr(i, totalLength, &m_scope->variableAt(m_table->get(i)))->get();
+        return preciseIndexMaskPtr(i, totalLength, storage + (i - namedLength))->get();
     }
 
     void setIndexQuickly(VM& vm, uint32_t i, JSValue value)
     {
         ASSERT_WITH_SECURITY_IMPLICATION(isMappedArgument(i));
+        WriteBarrier<Unknown>* storage = overflowStorage();
+        unsigned totalLength = storageHeader(storage).totalLength;
         unsigned namedLength = m_table->length();
         if (i < namedLength)
-            m_scope->variableAt(m_table->get(i)).set(vm, m_scope.get(), value);
+            preciseIndexMaskPtr(i, totalLength, &m_scope->variableAt(m_table->get(i)))->set(vm, m_scope.get(), value);
         else
-            overflowStorage()[i - namedLength].set(vm, this, value);
+            preciseIndexMaskPtr(i, totalLength, storage + (i - namedLength))->set(vm, this, value);
     }
 
-    WriteBarrier<JSFunction>& callee()
+    JSFunction* callee()
     {
-        return m_callee;
+        return m_callee.get();
     }
 
-    bool overrodeThings() const { return m_overrodeThings; }
+    bool overrodeThings() const { return storageHeader().overrodeThings; }
     void overrideThings(VM&);
     void overrideThingsIfNecessary(VM&);
     void unmapArgument(VM&, uint32_t index);
@@ -143,32 +148,55 @@
     
     static Structure* createStructure(VM&, JSGlobalObject*, JSValue prototype);
     
-    static ptrdiff_t offsetOfOverrodeThings() { return OBJECT_OFFSETOF(ScopedArguments, m_overrodeThings); }
-    static ptrdiff_t offsetOfTotalLength() { return OBJECT_OFFSETOF(ScopedArguments, m_totalLength); }
+    static ptrdiff_t offsetOfStorage() { return OBJECT_OFFSETOF(ScopedArguments, m_storage); }
+    static ptrdiff_t offsetOfOverrodeThingsInStorage() { return OBJECT_OFFSETOF(StorageHeader, overrodeThings) - sizeof(WriteBarrier<Unknown>); }
+    static ptrdiff_t offsetOfTotalLengthInStorage() { return OBJECT_OFFSETOF(StorageHeader, totalLength) - sizeof(WriteBarrier<Unknown>); }
     static ptrdiff_t offsetOfTable() { return OBJECT_OFFSETOF(ScopedArguments, m_table); }
     static ptrdiff_t offsetOfScope() { return OBJECT_OFFSETOF(ScopedArguments, m_scope); }
     
-    static size_t overflowStorageOffset()
+    static size_t allocationSize(size_t inlineSize)
     {
-        return WTF::roundUpToMultipleOf<sizeof(WriteBarrier<Unknown>)>(sizeof(ScopedArguments));
+        RELEASE_ASSERT(!inlineSize);
+        return sizeof(ScopedArguments);
     }
     
-    static size_t allocationSize(Checked<size_t> overflowArgumentsLength)
+    static size_t storageSize(Checked<size_t> capacity)
     {
-        return (overflowStorageOffset() + sizeof(WriteBarrier<Unknown>) * overflowArgumentsLength).unsafeGet();
+        return (sizeof(WriteBarrier<Unknown>) * (capacity + static_cast<size_t>(1))).unsafeGet();
     }
-
+    
+    static size_t storageHeaderSize() { return sizeof(WriteBarrier<Unknown>); }
+    
 private:
+    struct StorageHeader {
+        unsigned totalLength;
+        bool overrodeThings; // True if length, callee, and caller are fully materialized in the object.
+    };
+    
     WriteBarrier<Unknown>* overflowStorage() const
     {
-        return bitwise_cast<WriteBarrier<Unknown>*>(bitwise_cast<char*>(this) + overflowStorageOffset());
+        return m_storage.get().unpoisoned();
     }
     
-    bool m_overrodeThings; // True if length, callee, and caller are fully materialized in the object.
-    unsigned m_totalLength; // The length of declared plus overflow arguments.
-    WriteBarrier<JSFunction> m_callee;
-    WriteBarrier<ScopedArgumentsTable> m_table;
-    WriteBarrier<JSLexicalEnvironment> m_scope;
+    static StorageHeader& storageHeader(WriteBarrier<Unknown>* storage)
+    {
+        static_assert(sizeof(StorageHeader) <= sizeof(WriteBarrier<Unknown>), "StorageHeader needs to be no bigger than a JSValue");
+        return *bitwise_cast<StorageHeader*>(storage - 1);
+    }
+    
+    StorageHeader& storageHeader() const
+    {
+        return storageHeader(overflowStorage());
+    }
+    
+    template<typename T>
+    using PoisonedBarrier = PoisonedWriteBarrier<ScopedArgumentsPoison, T>;
+    
+    PoisonedBarrier<JSFunction> m_callee;
+    PoisonedBarrier<ScopedArgumentsTable> m_table;
+    PoisonedBarrier<JSLexicalEnvironment> m_scope;
+    
+    AuxiliaryBarrier<Poisoned<ScopedArgumentsPoison, WriteBarrier<Unknown>*>> m_storage;
 };
 
 } // namespace JSC
_______________________________________________
webkit-changes mailing list
[email protected]
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to