Changeset 227874 in webkit
- Timestamp:
- Jan 30, 2018, 9:23:52 PM (7 years ago)
- Location:
- trunk/Source
- Files:
-
- 20 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/Source/JavaScriptCore/ChangeLog
r227872 r227874 1 2018-01-30 Mark Lam <mark.lam@apple.com> 2 3 Apply poisoning to TypedArray vector pointers. 4 https://bugs.webkit.org/show_bug.cgi?id=182155 5 <rdar://problem/36286266> 6 7 Reviewed by JF Bastien. 8 9 The TypeArray's vector pointer is now poisoned. The poison value is chosen based 10 on a TypeArray's jsType. The JSType must be between FirstTypedArrayType and 11 LastTypedArrayType. At runtime, we enforce that the index is well-behaved by 12 masking it against TypedArrayPoisonIndexMask. TypedArrayPoisonIndexMask (16) is 13 the number of TypedArray types (10) rounded up to the next power of 2. 14 Accordingly, we reserve an array of TypedArrayPoisonIndexMask poisons so that we 15 can use index masking on the index, and be guaranteed that the masked index will 16 be within bounds of the poisons array. 17 18 1. Fixed both DFG and FTL versions of compileGetTypedArrayByteOffset() to not 19 do any unnecessary work if the TypedArray vector is null. 20 21 FTL's cagedMayBeNull() is no longer needed because it is only used by 22 compileGetTypedArrayByteOffset(), and we need to enhance it to handle unpoisoning 23 in a TypedArray specific way. So, might as well do the work inline in 24 compileGetTypedArrayByteOffset() instead. 25 26 2. Removed an unnecessary null-check in DFGSpeculativeJIT's compileNewTypedArrayWithSize() 27 because there's already a null check above it that ensures that sizeGPR is 28 never null. 29 30 3. In LLInt's _llint_op_get_by_val, move the TypedArray length check before the 31 loading of the vector for unpoisoning and uncaging. We don't need the vector 32 if the length is 0. 33 34 Implementation notes on the need to null check the TypeArray vector: 35 36 1. DFG::SpeculativeJIT::jumpForTypedArrayIsNeuteredIfOutOfBounds() does not need a 37 m_poisonedVector null check because the function is a null check. 38 39 2. DFG::SpeculativeJIT::compileGetIndexedPropertyStorage() does not need a 40 m_poisonedVector null check because it is followed by a call to 41 cageTypedArrayStorage() which assumes that storageReg cannot be null. 42 43 3. DFG::SpeculativeJIT::compileGetTypedArrayByteOffset() already has a 44 m_poisonedVector null check. 45 46 4. DFG::SpeculativeJIT::compileNewTypedArrayWithSize() does not need a vector null 47 check because the poisoning code is preceded by a sizeGPR null check, which 48 ensures that the storageGPR (vector to be poisoned) is not null. 49 50 5. FTL's compileGetIndexedPropertyStorage() does not need a m_poisonedVector null 51 check because it is followed by a call to caged() which assumes that the 52 vector cannot be null. 53 54 6. FTL's compileGetTypedArrayByteOffset() already has a m_poisonedVector null check. 55 56 7. FTL's compileNewTypedArray() does not need a vector null check because the 57 poisoning code is preceded by a size null check, which ensures that the 58 storage (vector to be poisoned) is not null. 59 60 8. FTL's speculateTypedArrayIsNotNeutered() does not need a 61 m_poisonedVector null check because the function is a null check. 62 63 9. IntrinsicGetterAccessCase::emitIntrinsicGetter()'s TypedArrayByteOffsetIntrinsic 64 case needs a null check so that it does not try to unpoison a null vector. 65 66 10. JIT::emitIntTypedArrayGetByVal() does not need a vector null check because 67 we already do a length check even before loading the vector. 68 69 11. JIT::emitFloatTypedArrayGetByVal() does not need a vector null check because 70 we already do a length check even before loading the vector. 71 72 12. JIT::emitIntTypedArrayPutByVal() does not need a vector null check because 73 we already do a length check even before loading the vector. 74 75 13. JIT::emitFloatTypedArrayPutByVal() does not need a vector null check because 76 we already do a length check even before loading the vector. 77 78 14. LLInt's loadTypedArrayCaged() does not need a vector null check because its 79 client will do a TypedArray length check before calling it. 80 81 * dfg/DFGFixupPhase.cpp: 82 (JSC::DFG::FixupPhase::checkArray): 83 * dfg/DFGNode.h: 84 (JSC::DFG::Node::hasArrayMode): 85 * dfg/DFGSpeculativeJIT.cpp: 86 (JSC::DFG::SpeculativeJIT::jumpForTypedArrayIsNeuteredIfOutOfBounds): 87 (JSC::DFG::SpeculativeJIT::compileGetIndexedPropertyStorage): 88 (JSC::DFG::SpeculativeJIT::compileGetTypedArrayByteOffset): 89 (JSC::DFG::SpeculativeJIT::compileNewTypedArrayWithSize): 90 * ftl/FTLAbstractHeapRepository.h: 91 * ftl/FTLLowerDFGToB3.cpp: 92 (JSC::FTL::DFG::LowerDFGToB3::compileGetIndexedPropertyStorage): 93 (JSC::FTL::DFG::LowerDFGToB3::compileGetTypedArrayByteOffset): 94 (JSC::FTL::DFG::LowerDFGToB3::compileNewTypedArray): 95 (JSC::FTL::DFG::LowerDFGToB3::speculateTypedArrayIsNotNeutered): 96 (JSC::FTL::DFG::LowerDFGToB3::cagedMayBeNull): Deleted. 97 * jit/IntrinsicEmitter.cpp: 98 (JSC::IntrinsicGetterAccessCase::emitIntrinsicGetter): 99 * jit/JITPropertyAccess.cpp: 100 (JSC::JIT::emitIntTypedArrayGetByVal): 101 (JSC::JIT::emitFloatTypedArrayGetByVal): 102 (JSC::JIT::emitIntTypedArrayPutByVal): 103 (JSC::JIT::emitFloatTypedArrayPutByVal): 104 * llint/LowLevelInterpreter.asm: 105 * llint/LowLevelInterpreter64.asm: 106 * offlineasm/arm64.rb: 107 * offlineasm/x86.rb: 108 * runtime/CagedBarrierPtr.h: 109 * runtime/JSArrayBufferView.cpp: 110 (JSC::JSArrayBufferView::JSArrayBufferView): 111 (JSC::JSArrayBufferView::finalize): 112 (JSC::JSArrayBufferView::neuter): 113 * runtime/JSArrayBufferView.h: 114 (JSC::JSArrayBufferView::vector const): 115 (JSC::JSArrayBufferView::offsetOfPoisonedVector): 116 (JSC::JSArrayBufferView::poisonFor): 117 (JSC::JSArrayBufferView::Poison::key): 118 (JSC::JSArrayBufferView::offsetOfVector): Deleted. 119 * runtime/JSCPoison.cpp: 120 (JSC::initializePoison): 121 * runtime/JSCPoison.h: 122 * runtime/JSGenericTypedArrayViewInlines.h: 123 (JSC::JSGenericTypedArrayView<Adaptor>::estimatedSize): 124 (JSC::JSGenericTypedArrayView<Adaptor>::visitChildren): 125 (JSC::JSGenericTypedArrayView<Adaptor>::slowDownAndWasteMemory): 126 * runtime/JSObject.h: 127 1 128 2018-01-30 Fujii Hironori <Hironori.Fujii@sony.com> 2 129 -
trunk/Source/JavaScriptCore/dfg/DFGFixupPhase.cpp
r227723 r227874 1 1 /* 2 * Copyright (C) 2012-201 7Apple Inc. All rights reserved.2 * Copyright (C) 2012-2018 Apple Inc. All rights reserved. 3 3 * 4 4 * Redistribution and use in source and binary forms, with or without … … 2871 2871 } 2872 2872 2873 ASSERT(arrayMode.type() == Array::String || arrayMode.typedArrayType() != NotTypedArray); 2873 2874 return m_insertionSet.insertNode( 2874 2875 m_indexInBlock, SpecNone, GetIndexedPropertyStorage, origin, -
trunk/Source/JavaScriptCore/dfg/DFGSpeculativeJIT.cpp
r227723 r227874 2846 2846 JITCompiler::Jump hasNullVector = m_jit.branchTestPtr( 2847 2847 MacroAssembler::Zero, 2848 MacroAssembler::Address(base, JSArrayBufferView::offsetOf Vector()));2848 MacroAssembler::Address(base, JSArrayBufferView::offsetOfPoisonedVector())); 2849 2849 speculationCheck(Uncountable, JSValueSource(), node, hasNullVector); 2850 2850 notWasteful.link(&m_jit); … … 6355 6355 6356 6356 default: 6357 ASSERT(isTypedView(node->arrayMode().typedArrayType())); 6358 6359 m_jit.loadPtr(JITCompiler::Address(baseReg, JSArrayBufferView::offsetOfVector()), storageReg); 6357 auto typedArrayType = node->arrayMode().typedArrayType(); 6358 ASSERT_UNUSED(typedArrayType, isTypedView(typedArrayType)); 6359 6360 m_jit.loadPtr(JITCompiler::Address(baseReg, JSArrayBufferView::offsetOfPoisonedVector()), storageReg); 6361 #if ENABLE(POISON) 6362 m_jit.xorPtr(JITCompiler::TrustedImmPtr(JSArrayBufferView::poisonFor(typedArrayType)), storageReg); 6363 #endif 6360 6364 cageTypedArrayStorage(storageReg); 6361 6365 break; … … 6374 6378 GPRReg vectorGPR = vector.gpr(); 6375 6379 GPRReg dataGPR = data.gpr(); 6376 6380 ASSERT(baseGPR != vectorGPR); 6381 ASSERT(baseGPR != dataGPR); 6382 ASSERT(vectorGPR != dataGPR); 6383 6384 #if ENABLE(POISON) 6385 GPRTemporary poison(this); 6386 GPRTemporary index(this); 6387 GPRReg poisonGPR = poison.gpr(); 6388 GPRReg indexGPR = index.gpr(); 6389 GPRReg arrayBufferGPR = poisonGPR; 6390 #else 6391 GPRReg arrayBufferGPR = dataGPR; 6392 #endif 6393 6377 6394 JITCompiler::Jump emptyByteOffset = m_jit.branch32( 6378 6395 MacroAssembler::NotEqual, … … 6380 6397 TrustedImm32(WastefulTypedArray)); 6381 6398 6399 m_jit.loadPtr(MacroAssembler::Address(baseGPR, JSArrayBufferView::offsetOfPoisonedVector()), vectorGPR); 6400 JITCompiler::Jump nullVector = m_jit.branchTestPtr(JITCompiler::Zero, vectorGPR); 6401 6382 6402 m_jit.loadPtr(MacroAssembler::Address(baseGPR, JSObject::butterflyOffset()), dataGPR); 6383 6403 m_jit.cage(Gigacage::JSValue, dataGPR); 6384 m_jit.loadPtr(MacroAssembler::Address(baseGPR, JSArrayBufferView::offsetOfVector()), vectorGPR); 6385 JITCompiler::Jump nullVector = m_jit.branchTestPtr(JITCompiler::Zero, vectorGPR); 6404 6405 #if ENABLE(POISON) 6406 m_jit.load8(JITCompiler::Address(baseGPR, JSCell::typeInfoTypeOffset()), indexGPR); 6407 m_jit.move(JITCompiler::TrustedImmPtr(&g_typedArrayPoisons), poisonGPR); 6408 m_jit.sub32(JITCompiler::TrustedImm32(FirstTypedArrayType), indexGPR); 6409 m_jit.and32(JITCompiler::TrustedImm32(TypedArrayPoisonIndexMask), indexGPR); 6410 m_jit.loadPtr(JITCompiler::BaseIndex(poisonGPR, indexGPR, JITCompiler::timesPtr()), poisonGPR); 6411 m_jit.xorPtr(poisonGPR, vectorGPR); 6412 #endif 6386 6413 cageTypedArrayStorage(vectorGPR); 6387 6414 6388 m_jit.loadPtr(MacroAssembler::Address(dataGPR, Butterfly::offsetOfArrayBuffer()), dataGPR);6415 m_jit.loadPtr(MacroAssembler::Address(dataGPR, Butterfly::offsetOfArrayBuffer()), arrayBufferGPR); 6389 6416 // FIXME: This needs caging. 6390 6417 // https://bugs.webkit.org/show_bug.cgi?id=175515 6391 m_jit.loadPtr(MacroAssembler::Address( dataGPR, ArrayBuffer::offsetOfData()), dataGPR);6418 m_jit.loadPtr(MacroAssembler::Address(arrayBufferGPR, ArrayBuffer::offsetOfData()), dataGPR); 6392 6419 m_jit.subPtr(dataGPR, vectorGPR); 6393 6420 … … 9026 9053 storageGPR, m_jit.vm()->primitiveGigacageAuxiliarySpace, scratchGPR, scratchGPR, 9027 9054 scratchGPR2, slowCases); 9028 9029 MacroAssembler::Jump done = m_jit.branchTest32(MacroAssembler::Zero, sizeGPR); 9055 9030 9056 m_jit.move(sizeGPR, scratchGPR); 9031 9057 if (elementSize(typedArrayType) != 4) { … … 9045 9071 MacroAssembler::BaseIndex(storageGPR, scratchGPR, MacroAssembler::TimesFour)); 9046 9072 m_jit.branchTest32(MacroAssembler::NonZero, scratchGPR).linkTo(loop, &m_jit); 9047 done.link(&m_jit);9048 9073 9049 9074 auto butterfly = TrustedImmPtr(nullptr); … … 9053 9078 slowCases); 9054 9079 9080 #if ENABLE(POISON) 9081 m_jit.move(storageGPR, scratchGPR); 9082 m_jit.xorPtr(TrustedImmPtr(JSArrayBufferView::poisonFor(typedArrayType)), scratchGPR); 9083 m_jit.storePtr( 9084 scratchGPR, 9085 MacroAssembler::Address(resultGPR, JSArrayBufferView::offsetOfPoisonedVector())); 9086 #else 9055 9087 m_jit.storePtr( 9056 9088 storageGPR, 9057 MacroAssembler::Address(resultGPR, JSArrayBufferView::offsetOfVector())); 9089 MacroAssembler::Address(resultGPR, JSArrayBufferView::offsetOfPoisonedVector())); 9090 #endif 9058 9091 m_jit.store32( 9059 9092 sizeGPR, -
trunk/Source/JavaScriptCore/ftl/FTLAbstractHeapRepository.h
r227617 r227874 60 60 macro(JSArrayBufferView_length, JSArrayBufferView::offsetOfLength()) \ 61 61 macro(JSArrayBufferView_mode, JSArrayBufferView::offsetOfMode()) \ 62 macro(JSArrayBufferView_ vector, JSArrayBufferView::offsetOfVector()) \62 macro(JSArrayBufferView_poisonedVector, JSArrayBufferView::offsetOfPoisonedVector()) \ 63 63 macro(JSCell_cellState, JSCell::cellStateOffset()) \ 64 64 macro(JSCell_header, 0) \ … … 150 150 macro(HasOwnPropertyCache, 0, sizeof(HasOwnPropertyCache::Entry)) \ 151 151 macro(JSFixedArray_buffer, JSFixedArray::offsetOfData(), sizeof(EncodedJSValue)) \ 152 152 macro(TypedArrayPoisons, 0, sizeof(uintptr_t)) \ 153 153 154 #define FOR_EACH_NUMBERED_ABSTRACT_HEAP(macro) \ 154 155 macro(properties) -
trunk/Source/JavaScriptCore/ftl/FTLLowerDFGToB3.cpp
r227723 r227874 3474 3474 3475 3475 DFG_ASSERT(m_graph, m_node, isTypedView(m_node->arrayMode().typedArrayType())); 3476 setStorage(caged(Gigacage::Primitive, m_out.loadPtr(cell, m_heaps.JSArrayBufferView_vector))); 3476 LValue poisonedVector = m_out.loadPtr(cell, m_heaps.JSArrayBufferView_poisonedVector); 3477 #if ENABLE(POISON) 3478 auto typedArrayType = m_node->arrayMode().typedArrayType(); 3479 LValue vector = m_out.bitXor(m_out.constIntPtr(JSArrayBufferView::poisonFor(typedArrayType)), poisonedVector); 3480 #else 3481 LValue vector = poisonedVector; 3482 #endif 3483 setStorage(caged(Gigacage::Primitive, vector)); 3477 3484 } 3478 3485 … … 3496 3503 LBasicBlock simpleCase = m_out.newBlock(); 3497 3504 LBasicBlock wastefulCase = m_out.newBlock(); 3505 LBasicBlock notNull = m_out.newBlock(); 3498 3506 LBasicBlock continuation = m_out.newBlock(); 3499 3507 … … 3509 3517 m_out.jump(continuation); 3510 3518 3511 m_out.appendTo(wastefulCase, continuation); 3512 3513 LValue vectorPtr = cagedMayBeNull( 3514 Gigacage::Primitive, 3515 m_out.loadPtr(basePtr, m_heaps.JSArrayBufferView_vector)); 3519 m_out.appendTo(wastefulCase, notNull); 3520 3521 LValue poisonedVector = m_out.loadPtr(basePtr, m_heaps.JSArrayBufferView_poisonedVector); 3522 ValueFromBlock nullVectorOut = m_out.anchor(poisonedVector); 3523 m_out.branch(poisonedVector, unsure(notNull), unsure(continuation)); 3524 3525 m_out.appendTo(notNull, continuation); 3526 3516 3527 LValue butterflyPtr = caged(Gigacage::JSValue, m_out.loadPtr(basePtr, m_heaps.JSObject_butterfly)); 3517 3528 LValue arrayBufferPtr = m_out.loadPtr(butterflyPtr, m_heaps.Butterfly_arrayBuffer); 3529 3530 #if ENABLE(POISON) 3531 LValue jsType = m_out.load8ZeroExt32(basePtr, m_heaps.JSCell_typeInfoType); 3532 LValue typeIndex = m_out.sub(jsType, m_out.constInt32(FirstTypedArrayType)); 3533 LValue maskedTypeIndex = m_out.zeroExtPtr(m_out.bitAnd(typeIndex, m_out.constInt32(TypedArrayPoisonIndexMask))); 3534 LValue poisonsBasePtr = m_out.constIntPtr(&g_typedArrayPoisons); 3535 LValue poison = m_out.loadPtr(m_out.baseIndex(m_heaps.TypedArrayPoisons, poisonsBasePtr, maskedTypeIndex)); 3536 poisonedVector = m_out.bitXor(poisonedVector, poison); 3537 #endif 3538 LValue vectorPtr = caged(Gigacage::Primitive, poisonedVector); 3539 3518 3540 // FIXME: This needs caging. 3519 3541 // https://bugs.webkit.org/show_bug.cgi?id=175515 … … 3525 3547 m_out.appendTo(continuation, lastNext); 3526 3548 3527 setInt32(m_out.castToInt32(m_out.phi(pointerType(), simpleOut, wastefulOut)));3549 setInt32(m_out.castToInt32(m_out.phi(pointerType(), simpleOut, nullVectorOut, wastefulOut))); 3528 3550 } 3529 3551 … … 5638 5660 allocateObject<JSArrayBufferView>(structure, m_out.intPtrZero, indexingMask, slowCase); 5639 5661 5640 m_out.storePtr(storage, fastResultValue, m_heaps.JSArrayBufferView_vector); 5662 #if ENABLE(POISON) 5663 storage = m_out.bitXor(m_out.constIntPtr(JSArrayBufferView::poisonFor(typedArrayType)), storage); 5664 #endif 5665 m_out.storePtr(storage, fastResultValue, m_heaps.JSArrayBufferView_poisonedVector); 5641 5666 m_out.store32(size, fastResultValue, m_heaps.JSArrayBufferView_length); 5642 5667 m_out.store32(m_out.constInt32(FastTypedArray), fastResultValue, m_heaps.JSArrayBufferView_mode); … … 12795 12820 // https://bugs.webkit.org/show_bug.cgi?id=175493 12796 12821 return m_out.opaque(result); 12797 }12798 12799 LValue cagedMayBeNull(Gigacage::Kind kind, LValue ptr)12800 {12801 LBasicBlock notNull = m_out.newBlock();12802 LBasicBlock continuation = m_out.newBlock();12803 12804 LBasicBlock lastNext = m_out.insertNewBlocksBefore(notNull);12805 12806 ValueFromBlock nullResult = m_out.anchor(ptr);12807 m_out.branch(ptr, unsure(notNull), unsure(continuation));12808 12809 m_out.appendTo(notNull, continuation);12810 ValueFromBlock notNullResult = m_out.anchor(caged(kind, ptr));12811 m_out.jump(continuation);12812 12813 m_out.appendTo(continuation, lastNext);12814 return m_out.phi(pointerType(), nullResult, notNullResult);12815 12822 } 12816 12823 … … 15016 15023 15017 15024 LBasicBlock lastNext = m_out.appendTo(isWasteful, continuation); 15018 LValue vector = m_out.loadPtr(base, m_heaps.JSArrayBufferView_ vector);15025 LValue vector = m_out.loadPtr(base, m_heaps.JSArrayBufferView_poisonedVector); 15019 15026 speculate(Uncountable, jsValueValue(vector), m_node, m_out.isZero64(vector)); 15020 15027 m_out.jump(continuation); -
trunk/Source/JavaScriptCore/jit/IntrinsicEmitter.cpp
r225071 r227874 1 1 /* 2 * Copyright (C) 2015-201 6Apple Inc. All rights reserved.2 * Copyright (C) 2015-2018 Apple Inc. All rights reserved. 3 3 * 4 4 * Redistribution and use in source and binary forms, with or without … … 108 108 GPRReg scratchGPR = state.scratchGPR; 109 109 110 CCallHelpers::Jump emptyByteOffset = jit.branch32(111 MacroAssembler:: NotEqual,110 CCallHelpers::Jump notEmptyByteOffset = jit.branch32( 111 MacroAssembler::Equal, 112 112 MacroAssembler::Address(baseGPR, JSArrayBufferView::offsetOfMode()), 113 113 TrustedImm32(WastefulTypedArray)); 114 114 115 jit.move(TrustedImmPtr(0), valueGPR); 116 CCallHelpers::Jump done = jit.jump(); 117 118 notEmptyByteOffset.link(&jit); 119 120 // We need to load the butterfly before the vector because baseGPR and valueGPR 121 // can be the same register. 115 122 jit.loadPtr(MacroAssembler::Address(baseGPR, JSObject::butterflyOffset()), scratchGPR); 116 jit.loadPtr(MacroAssembler::Address(baseGPR, JSArrayBufferView::offsetOfVector()), valueGPR); 123 jit.loadPtr(MacroAssembler::Address(baseGPR, JSArrayBufferView::offsetOfPoisonedVector()), valueGPR); 124 CCallHelpers::Jump nullVector = jit.branchTestPtr(MacroAssembler::Zero, valueGPR); 125 126 #if ENABLE(POISON) 127 auto typedArrayType = structure()->classInfo()->typedArrayStorageType; 128 jit.xorPtr(TrustedImmPtr(JSArrayBufferView::poisonFor(typedArrayType)), valueGPR); 129 #endif 117 130 jit.loadPtr(MacroAssembler::Address(scratchGPR, Butterfly::offsetOfArrayBuffer()), scratchGPR); 118 131 jit.loadPtr(MacroAssembler::Address(scratchGPR, ArrayBuffer::offsetOfData()), scratchGPR); 119 132 jit.subPtr(scratchGPR, valueGPR); 120 133 121 CCallHelpers::Jump done = jit.jump(); 122 123 emptyByteOffset.link(&jit); 124 jit.move(TrustedImmPtr(0), valueGPR); 125 134 nullVector.link(&jit); 126 135 done.link(&jit); 127 136 -
trunk/Source/JavaScriptCore/jit/JITPropertyAccess.cpp
r227643 r227874 1 1 /* 2 * Copyright (C) 2008-201 7Apple Inc. All rights reserved.2 * Copyright (C) 2008-2018 Apple Inc. All rights reserved. 3 3 * 4 4 * Redistribution and use in source and binary forms, with or without … … 1458 1458 } 1459 1459 1460 JIT::JumpList JIT::emitIntTypedArrayGetByVal(Instruction*, PatchableJump& badType, TypedArrayType type )1461 { 1462 ASSERT(isInt(type ));1460 JIT::JumpList JIT::emitIntTypedArrayGetByVal(Instruction*, PatchableJump& badType, TypedArrayType typeArrayType) 1461 { 1462 ASSERT(isInt(typeArrayType)); 1463 1463 1464 1464 // The best way to test the array type is to use the classInfo. We need to do so without … … 1481 1481 1482 1482 JumpList slowCases; 1483 1483 JSType jsType = typeForTypedArrayType(typeArrayType); 1484 1484 1485 load8(Address(base, JSCell::typeInfoTypeOffset()), scratch); 1485 badType = patchableBranch32(NotEqual, scratch, TrustedImm32( typeForTypedArrayType(type)));1486 badType = patchableBranch32(NotEqual, scratch, TrustedImm32(jsType)); 1486 1487 slowCases.append(branch32(AboveOrEqual, property, Address(base, JSArrayBufferView::offsetOfLength()))); 1487 loadPtr(Address(base, JSArrayBufferView::offsetOfVector()), scratch); 1488 loadPtr(Address(base, JSArrayBufferView::offsetOfPoisonedVector()), scratch); 1489 #if ENABLE(POISON) 1490 xorPtr(TrustedImmPtr(JSArrayBufferView::poisonFor(jsType)), scratch); 1491 #endif 1488 1492 cageConditionally(Gigacage::Primitive, scratch, scratch2); 1489 1493 1490 switch (elementSize(type )) {1494 switch (elementSize(typeArrayType)) { 1491 1495 case 1: 1492 if (JSC::isSigned(type ))1496 if (JSC::isSigned(typeArrayType)) 1493 1497 load8SignedExtendTo32(BaseIndex(scratch, property, TimesOne), resultPayload); 1494 1498 else … … 1496 1500 break; 1497 1501 case 2: 1498 if (JSC::isSigned(type ))1502 if (JSC::isSigned(typeArrayType)) 1499 1503 load16SignedExtendTo32(BaseIndex(scratch, property, TimesTwo), resultPayload); 1500 1504 else … … 1509 1513 1510 1514 Jump done; 1511 if (type == TypeUint32) {1515 if (typeArrayType == TypeUint32) { 1512 1516 Jump canBeInt = branch32(GreaterThanOrEqual, resultPayload, TrustedImm32(0)); 1513 1517 … … 1535 1539 } 1536 1540 1537 JIT::JumpList JIT::emitFloatTypedArrayGetByVal(Instruction*, PatchableJump& badType, TypedArrayType type )1538 { 1539 ASSERT(isFloat(type ));1541 JIT::JumpList JIT::emitFloatTypedArrayGetByVal(Instruction*, PatchableJump& badType, TypedArrayType typeArrayType) 1542 { 1543 ASSERT(isFloat(typeArrayType)); 1540 1544 1541 1545 #if USE(JSVALUE64) … … 1555 1559 1556 1560 JumpList slowCases; 1561 JSType jsType = typeForTypedArrayType(typeArrayType); 1557 1562 1558 1563 load8(Address(base, JSCell::typeInfoTypeOffset()), scratch); 1559 badType = patchableBranch32(NotEqual, scratch, TrustedImm32( typeForTypedArrayType(type)));1564 badType = patchableBranch32(NotEqual, scratch, TrustedImm32(jsType)); 1560 1565 slowCases.append(branch32(AboveOrEqual, property, Address(base, JSArrayBufferView::offsetOfLength()))); 1561 loadPtr(Address(base, JSArrayBufferView::offsetOfVector()), scratch); 1566 loadPtr(Address(base, JSArrayBufferView::offsetOfPoisonedVector()), scratch); 1567 #if ENABLE(POISON) 1568 xorPtr(TrustedImmPtr(JSArrayBufferView::poisonFor(jsType)), scratch); 1569 #endif 1562 1570 cageConditionally(Gigacage::Primitive, scratch, scratch2); 1563 1571 1564 switch (elementSize(type )) {1572 switch (elementSize(typeArrayType)) { 1565 1573 case 4: 1566 1574 loadFloat(BaseIndex(scratch, property, TimesFour), fpRegT0); … … 1589 1597 } 1590 1598 1591 JIT::JumpList JIT::emitIntTypedArrayPutByVal(Instruction* currentInstruction, PatchableJump& badType, TypedArrayType type )1599 JIT::JumpList JIT::emitIntTypedArrayPutByVal(Instruction* currentInstruction, PatchableJump& badType, TypedArrayType typeArrayType) 1592 1600 { 1593 1601 ArrayProfile* profile = currentInstruction[4].u.arrayProfile; 1594 ASSERT(isInt(type ));1602 ASSERT(isInt(typeArrayType)); 1595 1603 1596 1604 int value = currentInstruction[3].u.operand; … … 1611 1619 1612 1620 JumpList slowCases; 1613 1621 JSType jsType = typeForTypedArrayType(typeArrayType); 1622 1614 1623 load8(Address(base, JSCell::typeInfoTypeOffset()), earlyScratch); 1615 badType = patchableBranch32(NotEqual, earlyScratch, TrustedImm32( typeForTypedArrayType(type)));1624 badType = patchableBranch32(NotEqual, earlyScratch, TrustedImm32(jsType)); 1616 1625 Jump inBounds = branch32(Below, property, Address(base, JSArrayBufferView::offsetOfLength())); 1617 1626 emitArrayProfileOutOfBoundsSpecialCase(profile); … … 1629 1638 // We would be loading this into base as in get_by_val, except that the slow 1630 1639 // path expects the base to be unclobbered. 1631 loadPtr(Address(base, JSArrayBufferView::offsetOfVector()), lateScratch); 1640 loadPtr(Address(base, JSArrayBufferView::offsetOfPoisonedVector()), lateScratch); 1641 #if ENABLE(POISON) 1642 xorPtr(TrustedImmPtr(JSArrayBufferView::poisonFor(jsType)), lateScratch); 1643 #endif 1632 1644 cageConditionally(Gigacage::Primitive, lateScratch, lateScratch2); 1633 1645 1634 if (isClamped(type )) {1635 ASSERT(elementSize(type ) == 1);1636 ASSERT(!JSC::isSigned(type ));1646 if (isClamped(typeArrayType)) { 1647 ASSERT(elementSize(typeArrayType) == 1); 1648 ASSERT(!JSC::isSigned(typeArrayType)); 1637 1649 Jump inBounds = branch32(BelowOrEqual, earlyScratch, TrustedImm32(0xff)); 1638 1650 Jump tooBig = branch32(GreaterThan, earlyScratch, TrustedImm32(0xff)); … … 1645 1657 } 1646 1658 1647 switch (elementSize(type )) {1659 switch (elementSize(typeArrayType)) { 1648 1660 case 1: 1649 1661 store8(earlyScratch, BaseIndex(lateScratch, property, TimesOne)); … … 1662 1674 } 1663 1675 1664 JIT::JumpList JIT::emitFloatTypedArrayPutByVal(Instruction* currentInstruction, PatchableJump& badType, TypedArrayType type )1676 JIT::JumpList JIT::emitFloatTypedArrayPutByVal(Instruction* currentInstruction, PatchableJump& badType, TypedArrayType typeArrayType) 1665 1677 { 1666 1678 ArrayProfile* profile = currentInstruction[4].u.arrayProfile; 1667 ASSERT(isFloat(type ));1679 ASSERT(isFloat(typeArrayType)); 1668 1680 1669 1681 int value = currentInstruction[3].u.operand; … … 1684 1696 1685 1697 JumpList slowCases; 1686 1698 JSType jsType = typeForTypedArrayType(typeArrayType); 1699 1687 1700 load8(Address(base, JSCell::typeInfoTypeOffset()), earlyScratch); 1688 badType = patchableBranch32(NotEqual, earlyScratch, TrustedImm32( typeForTypedArrayType(type)));1701 badType = patchableBranch32(NotEqual, earlyScratch, TrustedImm32(jsType)); 1689 1702 Jump inBounds = branch32(Below, property, Address(base, JSArrayBufferView::offsetOfLength())); 1690 1703 emitArrayProfileOutOfBoundsSpecialCase(profile); … … 1715 1728 // We would be loading this into base as in get_by_val, except that the slow 1716 1729 // path expects the base to be unclobbered. 1717 loadPtr(Address(base, JSArrayBufferView::offsetOfVector()), lateScratch); 1730 loadPtr(Address(base, JSArrayBufferView::offsetOfPoisonedVector()), lateScratch); 1731 #if ENABLE(POISON) 1732 xorPtr(TrustedImmPtr(JSArrayBufferView::poisonFor(jsType)), lateScratch); 1733 #endif 1718 1734 cageConditionally(Gigacage::Primitive, lateScratch, lateScratch2); 1719 1735 1720 switch (elementSize(type )) {1736 switch (elementSize(typeArrayType)) { 1721 1737 case 4: 1722 1738 convertDoubleToFloat(fpRegT0, fpRegT0); -
trunk/Source/JavaScriptCore/llint/LowLevelInterpreter.asm
r227717 r227874 395 395 const FirstArrayType = constexpr FirstTypedArrayType 396 396 const NumberOfTypedArrayTypesExcludingDataView = constexpr NumberOfTypedArrayTypesExcludingDataView 397 const TypedArrayPoisonIndexMask = constexpr TypedArrayPoisonIndexMask 397 398 398 399 # Type flags constants. -
trunk/Source/JavaScriptCore/llint/LowLevelInterpreter64.asm
r227717 r227874 377 377 end 378 378 379 macro loadCaged(basePtr, mask, source, dest, scratch) 380 loadp source, dest 379 macro uncage(basePtr, mask, ptr, scratch) 381 380 if GIGACAGE_ENABLED and not C_LOOP 382 381 loadp basePtr, scratch 383 382 btpz scratch, .done 384 andp mask, dest385 addp scratch, dest383 andp mask, ptr 384 addp scratch, ptr 386 385 .done: 387 386 end 387 end 388 389 macro loadCaged(basePtr, mask, source, dest, scratch) 390 loadp source, dest 391 uncage(basePtr, mask, dest, scratch) 392 end 393 394 macro loadTypedArrayCaged(basePtr, mask, source, typeIndex, dest, scratch) 395 if POISON 396 andp TypedArrayPoisonIndexMask, typeIndex 397 leap _g_typedArrayPoisons, dest 398 loadp [dest, typeIndex, 8], dest 399 loadp source, scratch 400 xorp scratch, dest 401 else 402 loadp source, dest 403 end 404 uncage(basePtr, mask, dest, scratch) 388 405 end 389 406 … … 1542 1559 1543 1560 # Sweet, now we know that we have a typed array. Do some basic things now. 1544 loadCaged(_g_gigacageBasePtrs + Gigacage::BasePtrs::primitive, constexpr PRIMITIVE_GIGACAGE_MASK, JSArrayBufferView::m_vector[t0], t3, t5)1545 1561 biaeq t1, JSArrayBufferView::m_length[t0], .opGetByValSlow 1546 1562 loadTypedArrayCaged(_g_gigacageBasePtrs + Gigacage::BasePtrs::primitive, constexpr PRIMITIVE_GIGACAGE_MASK, JSArrayBufferView::m_poisonedVector[t0], t2, t3, t5) 1563 1547 1564 # Now bisect through the various types: 1548 1565 # Int8ArrayType, -
trunk/Source/JavaScriptCore/offlineasm/arm64.rb
r224171 r227874 273 273 newList << Instruction.new(codeOrigin, "globaladdr", [LabelReference.new(node.codeOrigin, labelRef.label), tmp]) 274 274 newList << Instruction.new(codeOrigin, node.opcode, [Address.new(node.codeOrigin, tmp, Immediate.new(node.codeOrigin, labelRef.offset)), node.operands[1]]) 275 else 276 newList << node 277 end 278 when "leai", "leap", "leaq" 279 labelRef = node.operands[0] 280 if labelRef.is_a? LabelReference 281 newList << Instruction.new(codeOrigin, "globaladdr", [LabelReference.new(node.codeOrigin, labelRef.label), node.operands[1]]) 275 282 else 276 283 newList << node -
trunk/Source/JavaScriptCore/offlineasm/x86.rb
r222549 r227874 469 469 "#{offset}(#{dst.x86Operand(kind)})" 470 470 end 471 def x86AddressOperand(addressKind) 472 # FIXME: Implement this on platforms that aren't Mach-O. 473 # https://bugs.webkit.org/show_bug.cgi?id=175104 474 "#{asmLabel}@GOTPCREL(%rip)" 475 end 471 476 end 472 477 … … 580 585 else 581 586 raise 587 end 588 end 589 590 def emitX86Lea(src, dst, kind) 591 if src.is_a? LabelReference 592 $asm.puts "movq #{src.asmLabel}@GOTPCREL(%rip), #{dst.x86Operand(:ptr)}" 593 $asm.puts "mov#{x86Suffix(kind)} #{orderOperands(dst.x86Operand(kind), dst.x86Operand(kind))}" 594 else 595 $asm.puts "lea#{x86Suffix(kind)} #{orderOperands(src.x86AddressOperand(kind), dst.x86Operand(kind))}" 582 596 end 583 597 end … … 1543 1557 $asm.puts "jnz #{operands[0].asmLabel}" 1544 1558 when "leai" 1545 $asm.puts "lea#{x86Suffix(:int)} #{orderOperands(operands[0].x86AddressOperand(:int), operands[1].x86Operand(:int))}"1559 emitX86Lea(operands[0], operands[1], :int) 1546 1560 when "leap" 1547 $asm.puts "lea#{x86Suffix(:ptr)} #{orderOperands(operands[0].x86AddressOperand(:ptr), operands[1].x86Operand(:ptr))}"1561 emitX86Lea(operands[0], operands[1], :ptr) 1548 1562 when "memfence" 1549 1563 sp = RegisterID.new(nil, "sp") -
trunk/Source/JavaScriptCore/runtime/CagedBarrierPtr.h
r221439 r227874 1 1 /* 2 * Copyright (C) 2017 Apple Inc. All rights reserved.2 * Copyright (C) 2017-2018 Apple Inc. All rights reserved. 3 3 * 4 4 * Redistribution and use in source and binary forms, with or without … … 27 27 28 28 #include "AuxiliaryBarrier.h" 29 #include <type_traits> 29 30 #include <wtf/CagedPtr.h> 31 32 namespace WTF { 33 34 template<typename Poison, typename T> struct PoisonedPtrTraits; 35 36 } // namespace WTF 30 37 31 38 namespace JSC { … … 36 43 // This is a convenient combo of AuxiliaryBarrier and CagedPtr. 37 44 38 template<Gigacage::Kind passedKind, typename T >45 template<Gigacage::Kind passedKind, typename T, typename PtrTraits = WTF::DumbPtrTraits<T>> 39 46 class CagedBarrierPtr { 40 47 public: … … 86 93 87 94 private: 88 AuxiliaryBarrier<CagedPtr<kind, T >> m_barrier;95 AuxiliaryBarrier<CagedPtr<kind, T, PtrTraits>> m_barrier; 89 96 }; 90 97 91 template<Gigacage::Kind passedKind >92 class CagedBarrierPtr<passedKind, void > {98 template<Gigacage::Kind passedKind, typename PtrTraits> 99 class CagedBarrierPtr<passedKind, void, PtrTraits> { 93 100 public: 94 101 static constexpr Gigacage::Kind kind = passedKind; … … 133 140 134 141 private: 135 AuxiliaryBarrier<CagedPtr<kind, void >> m_barrier;142 AuxiliaryBarrier<CagedPtr<kind, void, PtrTraits>> m_barrier; 136 143 }; 137 144 145 template<typename Poison, Gigacage::Kind passedKind, typename T> 146 using PoisonedCagedBarrierPtr = CagedBarrierPtr<passedKind, T, WTF::PoisonedPtrTraits<Poison, T>>; 147 138 148 } // namespace JSC -
trunk/Source/JavaScriptCore/runtime/JSArrayBufferView.cpp
r227617 r227874 1 1 /* 2 * Copyright (C) 2013-201 7Apple Inc. All rights reserved.2 * Copyright (C) 2013-2018 Apple Inc. All rights reserved. 3 3 * 4 4 * Redistribution and use in source and binary forms, with or without … … 133 133 { 134 134 setButterflyWithIndexingMask(vm, context.butterfly(), WTF::computeIndexingMask(length())); 135 m_ vector.setWithoutBarrier(context.vector());135 m_poisonedVector.setWithoutBarrier(context.vector()); 136 136 } 137 137 … … 194 194 ASSERT(thisObject->m_mode == OversizeTypedArray || thisObject->m_mode == WastefulTypedArray); 195 195 if (thisObject->m_mode == OversizeTypedArray) 196 Gigacage::free(Gigacage::Primitive, thisObject->m_ vector.get());196 Gigacage::free(Gigacage::Primitive, thisObject->m_poisonedVector.get()); 197 197 } 198 198 … … 212 212 RELEASE_ASSERT(!isShared()); 213 213 m_length = 0; 214 m_ vector.clear();214 m_poisonedVector.clear(); 215 215 } 216 216 -
trunk/Source/JavaScriptCore/runtime/JSArrayBufferView.h
r221439 r227874 1 1 /* 2 * Copyright (C) 2013 , 2016Apple Inc. All rights reserved.2 * Copyright (C) 2013-2018 Apple Inc. All rights reserved. 3 3 * 4 4 * Redistribution and use in source and binary forms, with or without … … 27 27 28 28 #include "AuxiliaryBarrier.h" 29 #include "CagedBarrierPtr.h" 30 #include "JSCPoison.h" 29 31 #include "JSObject.h" 32 #include "TypedArrayType.h" 33 #include <wtf/MathExtras.h> 30 34 31 35 namespace JSC { 32 36 33 37 class LLIntOffsetsExtractor; 38 39 // Since we'll be indexing into the g_typedArrayPoisons array based on the TypedArray type, 40 // we'll index mask the index value and round up to the array size to the next power of 2 to 41 // ensure that we'll never be able to access beyond the bounds of this array. 42 static constexpr uint32_t NumberOfTypedArrayPoisons = WTF::roundUpToPowerOfTwo(NumberOfTypedArrayTypes); 43 static constexpr uint32_t TypedArrayPoisonIndexMask = NumberOfTypedArrayPoisons - 1; 34 44 35 45 // This class serves two purposes: … … 168 178 void neuter(); 169 179 170 void* vector() const { return m_ vector.getMayBeNull(); }180 void* vector() const { return m_poisonedVector.getMayBeNull(); } 171 181 172 182 unsigned byteOffset(); … … 175 185 DECLARE_EXPORT_INFO; 176 186 177 static ptrdiff_t offsetOf Vector() { return OBJECT_OFFSETOF(JSArrayBufferView, m_vector); }187 static ptrdiff_t offsetOfPoisonedVector() { return OBJECT_OFFSETOF(JSArrayBufferView, m_poisonedVector); } 178 188 static ptrdiff_t offsetOfLength() { return OBJECT_OFFSETOF(JSArrayBufferView, m_length); } 179 189 static ptrdiff_t offsetOfMode() { return OBJECT_OFFSETOF(JSArrayBufferView, m_mode); } … … 181 191 static RefPtr<ArrayBufferView> toWrapped(VM&, JSValue); 182 192 193 static uintptr_t poisonFor(JSType type) 194 { 195 return g_typedArrayPoisons[(type - FirstTypedArrayType) & TypedArrayPoisonIndexMask]; 196 } 197 198 static uintptr_t poisonFor(TypedArrayType typedArrayType) 199 { 200 ASSERT(isTypedView(typedArrayType)); 201 return poisonFor(typeForTypedArrayType(typedArrayType)); 202 } 203 183 204 private: 184 205 static void finalize(JSCell*); … … 191 212 static String toStringName(const JSObject*, ExecState*); 192 213 193 CagedBarrierPtr<Gigacage::Primitive, void> m_vector; 214 class Poison { 215 public: 216 template<typename PoisonedType> 217 inline static uintptr_t key(const PoisonedType* poisonedPtr) 218 { 219 uintptr_t poisonedVectorAddress = bitwise_cast<uintptr_t>(poisonedPtr); 220 uintptr_t baseAddress = poisonedVectorAddress - OBJECT_OFFSETOF(JSArrayBufferView, m_poisonedVector); 221 JSArrayBufferView* thisObject = bitwise_cast<JSArrayBufferView*>(baseAddress); 222 return poisonFor(thisObject->type()); 223 } 224 }; 225 226 PoisonedCagedBarrierPtr<Poison, Gigacage::Primitive, void> m_poisonedVector; 194 227 uint32_t m_length; 195 228 TypedArrayMode m_mode; -
trunk/Source/JavaScriptCore/runtime/JSCPoison.cpp
r227527 r227874 27 27 #include "JSCPoison.h" 28 28 29 #include "JSArrayBufferView.h" 29 30 #include "Options.h" 30 31 #include <mutex> … … 36 37 uintptr_t POISON_KEY_NAME(poisonID); 37 38 FOR_EACH_JSC_POISON(DEFINE_POISON) 39 40 uintptr_t g_typedArrayPoisons[NumberOfTypedArrayPoisons]; 38 41 39 42 void initializePoison() … … 48 51 49 52 FOR_EACH_JSC_POISON(INITIALIZE_POISON) 53 54 for (uint32_t i = 0; i < NumberOfTypedArrayPoisons; ++i) 55 g_typedArrayPoisons[i] = makePoison(); 50 56 }); 51 57 } -
trunk/Source/JavaScriptCore/runtime/JSCPoison.h
r227527 r227874 65 65 #undef DECLARE_POISON 66 66 67 extern "C" JS_EXPORTDATA uintptr_t g_typedArrayPoisons[]; 68 67 69 struct ClassInfo; 68 70 -
trunk/Source/JavaScriptCore/runtime/JSGenericTypedArrayViewInlines.h
r226461 r227874 1 1 /* 2 * Copyright (C) 2013 , 2016Apple Inc. All rights reserved.2 * Copyright (C) 2013-2018 Apple Inc. All rights reserved. 3 3 * 4 4 * Redistribution and use in source and binary forms, with or without … … 505 505 if (thisObject->m_mode == OversizeTypedArray) 506 506 return Base::estimatedSize(thisObject) + thisObject->byteSize(); 507 if (thisObject->m_mode == FastTypedArray && thisObject->m_ vector)507 if (thisObject->m_mode == FastTypedArray && thisObject->m_poisonedVector) 508 508 return Base::estimatedSize(thisObject) + thisObject->byteSize(); 509 509 … … 518 518 switch (thisObject->m_mode) { 519 519 case FastTypedArray: { 520 if (void* vector = thisObject->m_ vector.getMayBeNull())520 if (void* vector = thisObject->m_poisonedVector.getMayBeNull()) 521 521 visitor.markAuxiliary(vector); 522 522 break; … … 586 586 587 587 thisObject->butterfly()->indexingHeader()->setArrayBuffer(buffer.get()); 588 thisObject->m_ vector.setWithoutBarrier(buffer->data());588 thisObject->m_poisonedVector.setWithoutBarrier(buffer->data()); 589 589 WTF::storeStoreFence(); 590 590 thisObject->m_mode = WastefulTypedArray; -
trunk/Source/JavaScriptCore/runtime/JSObject.h
r226000 r227874 25 25 #include "ArrayConventions.h" 26 26 #include "ArrayStorage.h" 27 #include "AuxiliaryBarrier.h" 27 28 #include "Butterfly.h" 28 29 #include "CPU.h" 29 #include "CagedBarrierPtr.h"30 30 #include "CallFrame.h" 31 31 #include "ClassInfo.h" -
trunk/Source/WTF/ChangeLog
r227872 r227874 1 2018-01-30 Mark Lam <mark.lam@apple.com> 2 3 Apply poisoning to TypedArray vector pointers. 4 https://bugs.webkit.org/show_bug.cgi?id=182155 5 <rdar://problem/36286266> 6 7 Reviewed by JF Bastien. 8 9 1. Added the ability to poison a CagedPtr. 10 11 2. Prevent CagedPtr from being implicitly instantiated, and add operator= methods 12 instead. This is because implicitly instantiated CagedPtrs with a poisoned 13 trait may silently use a wrong poison value. 14 15 * wtf/CagedPtr.h: 16 (WTF::CagedPtr::CagedPtr): 17 (WTF::CagedPtr::get const): 18 (WTF::CagedPtr::operator=): 19 1 20 2018-01-30 Fujii Hironori <Hironori.Fujii@sony.com> 2 21 -
trunk/Source/WTF/wtf/CagedPtr.h
r221439 r227874 26 26 #pragma once 27 27 28 #include <wtf/DumbPtrTraits.h> 28 29 #include <wtf/Gigacage.h> 29 30 30 31 namespace WTF { 31 32 32 template<Gigacage::Kind passedKind, typename T >33 template<Gigacage::Kind passedKind, typename T, typename PtrTraits = DumbPtrTraits<T>> 33 34 class CagedPtr { 34 35 public: 35 36 static constexpr Gigacage::Kind kind = passedKind; 36 37 CagedPtr(T* ptr = nullptr) 37 38 CagedPtr() : CagedPtr(nullptr) { } 39 CagedPtr(std::nullptr_t) : m_ptr(nullptr) { } 40 41 explicit CagedPtr(T* ptr) 38 42 : m_ptr(ptr) 39 43 { … … 43 47 { 44 48 ASSERT(m_ptr); 45 return Gigacage::caged(kind, m_ptr);49 return Gigacage::caged(kind, PtrTraits::unwrap(m_ptr)); 46 50 } 47 51 … … 52 56 return get(); 53 57 } 54 58 59 CagedPtr& operator=(T* ptr) 60 { 61 m_ptr = ptr; 62 return *this; 63 } 64 65 CagedPtr& operator=(T*&& ptr) 66 { 67 m_ptr = WTFMove(ptr); 68 return *this; 69 } 70 55 71 bool operator==(const CagedPtr& other) const 56 72 { … … 75 91 76 92 protected: 77 T*m_ptr;93 typename PtrTraits::StorageType m_ptr; 78 94 }; 79 95 80 template<Gigacage::Kind passedKind >81 class CagedPtr<passedKind, void > {96 template<Gigacage::Kind passedKind, typename PtrTraits> 97 class CagedPtr<passedKind, void, PtrTraits> { 82 98 public: 83 99 static constexpr Gigacage::Kind kind = passedKind; 84 85 CagedPtr(void* ptr = nullptr) 100 101 CagedPtr() : CagedPtr(nullptr) { } 102 CagedPtr(std::nullptr_t) : m_ptr(nullptr) { } 103 104 explicit CagedPtr(void* ptr) 86 105 : m_ptr(ptr) 87 106 { … … 91 110 { 92 111 ASSERT(m_ptr); 93 return Gigacage::caged(kind, m_ptr);112 return Gigacage::caged(kind, PtrTraits::unwrap(m_ptr)); 94 113 } 95 114 … … 100 119 return get(); 101 120 } 102 121 122 CagedPtr& operator=(void* ptr) 123 { 124 m_ptr = ptr; 125 return *this; 126 } 127 103 128 bool operator==(const CagedPtr& other) const 104 129 { … … 117 142 118 143 protected: 119 void*m_ptr;144 typename PtrTraits::StorageType m_ptr; 120 145 }; 121 146
Note:
See TracChangeset
for help on using the changeset viewer.