Skip to content

stdlib: enable runtime checking for COW support by default in assert builds. #32385

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 2 commits into from
Jul 3, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 11 additions & 2 deletions lib/SILGen/SILGenExpr.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2109,7 +2109,8 @@ VarargsInfo Lowering::emitBeginVarargs(SILGenFunction &SGF, SILLocation loc,
}

ManagedValue Lowering::emitEndVarargs(SILGenFunction &SGF, SILLocation loc,
VarargsInfo &&varargs) {
VarargsInfo &&varargs,
unsigned numElements) {
// Kill the abort cleanup.
SGF.Cleanups.setCleanupState(varargs.getAbortCleanup(), CleanupState::Dead);

Expand All @@ -2118,6 +2119,14 @@ ManagedValue Lowering::emitEndVarargs(SILGenFunction &SGF, SILLocation loc,
if (array.hasCleanup())
SGF.Cleanups.setCleanupState(array.getCleanup(), CleanupState::Active);

// Array literals only need to be finalized, if the array is really allocated.
// In case of zero elements, no allocation is done, but the empty-array
// singleton is used. "Finalization" means to emit an end_cow_mutation
// instruction on the array. As the empty-array singleton is a read-only and
// shared object, it's not legal to do a end_cow_mutation on it.
if (numElements == 0)
return array;

return SGF.emitUninitializedArrayFinalization(loc, std::move(array));
}

Expand Down Expand Up @@ -3870,7 +3879,7 @@ RValue RValueEmitter::visitCollectionExpr(CollectionExpr *E, SGFContext C) {
SGF.Cleanups.setCleanupState(destCleanup, CleanupState::Dead);

RValue array(SGF, loc, arrayType,
emitEndVarargs(SGF, loc, std::move(varargsInfo)));
emitEndVarargs(SGF, loc, std::move(varargsInfo), E->getNumElements()));

array = scope.popPreservingValue(std::move(array));

Expand Down
3 changes: 2 additions & 1 deletion lib/SILGen/Varargs.h
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,8 @@ VarargsInfo emitBeginVarargs(SILGenFunction &SGF, SILLocation loc,

/// Successfully end a varargs emission sequence.
ManagedValue emitEndVarargs(SILGenFunction &SGF, SILLocation loc,
VarargsInfo &&varargs);
VarargsInfo &&varargs,
unsigned numElements);

} // end namespace Lowering
} // end namespace swift
Expand Down
16 changes: 9 additions & 7 deletions lib/SILOptimizer/Mandatory/OSLogOptimization.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -540,13 +540,15 @@ static SILValue emitCodeForConstantArray(ArrayRef<SILValue> elements,
assert(arrayAllocateFun);

SILFunction *arrayFinalizeFun = nullptr;
if (FuncDecl *arrayFinalizeDecl = astContext.getFinalizeUninitializedArray()) {
std::string finalizeMangledName =
SILDeclRef(arrayFinalizeDecl, SILDeclRef::Kind::Func).mangle();
arrayFinalizeFun =
module.findFunction(finalizeMangledName, SILLinkage::SharedExternal);
assert(arrayFinalizeFun);
module.linkFunction(arrayFinalizeFun);
if (numElements != 0) {
if (FuncDecl *arrayFinalizeDecl = astContext.getFinalizeUninitializedArray()) {
std::string finalizeMangledName =
SILDeclRef(arrayFinalizeDecl, SILDeclRef::Kind::Func).mangle();
arrayFinalizeFun =
module.findFunction(finalizeMangledName, SILLinkage::SharedExternal);
assert(arrayFinalizeFun);
module.linkFunction(arrayFinalizeFun);
}
}

// Call the _allocateUninitializedArray function with numElementsSIL. The
Expand Down
9 changes: 0 additions & 9 deletions stdlib/public/core/ContiguousArrayBuffer.swift
Original file line number Diff line number Diff line change
Expand Up @@ -454,18 +454,12 @@ internal struct _ContiguousArrayBuffer<Element>: _ArrayBufferProtocol {
@_alwaysEmitIntoClient
internal var isImmutable: Bool {
get {
// TODO: Enable COW runtime checks by default (when INTERNAL_CHECKS_ENABLED
// is set). Currently there is a problem with remote AST which needs to be
// fixed.
#if ENABLE_COW_RUNTIME_CHECKS
if #available(macOS 9999, iOS 9999, watchOS 9999, tvOS 9999, *) {
return capacity == 0 || _swift_isImmutableCOWBuffer(_storage)
}
#endif
return true
}
nonmutating set {
#if ENABLE_COW_RUNTIME_CHECKS
if #available(macOS 9999, iOS 9999, watchOS 9999, tvOS 9999, *) {
if newValue {
if capacity > 0 {
Expand All @@ -481,17 +475,14 @@ internal struct _ContiguousArrayBuffer<Element>: _ArrayBufferProtocol {
"re-setting mutable array buffer to mutable")
}
}
#endif
}
}

@_alwaysEmitIntoClient
internal var isMutable: Bool {
#if ENABLE_COW_RUNTIME_CHECKS
if #available(macOS 9999, iOS 9999, watchOS 9999, tvOS 9999, *) {
return !_swift_isImmutableCOWBuffer(_storage)
}
#endif
return true
}
#endif
Expand Down
4 changes: 1 addition & 3 deletions test/SILGen/keypaths.swift
Original file line number Diff line number Diff line change
Expand Up @@ -486,9 +486,7 @@ func test_variadics() {
// CHECK: [[FN_REF:%[0-9]+]] = function_ref @$ss27_allocateUninitializedArrayySayxG_BptBwlF
// CHECK: [[MAKE_ARR:%[0-9]+]] = apply [[FN_REF]]<Int>([[ARR_COUNT]])
// CHECK: ([[ARR:%[0-9]+]], %{{[0-9]+}}) = destructure_tuple [[MAKE_ARR]] : $(Array<Int>, Builtin.RawPointer)
// CHECK: [[FIN_REF:%[0-9]+]] = function_ref @$ss27_finalizeUninitializedArrayySayxGABnlF
// CHECK: [[FIN_ARR:%[0-9]+]] = apply [[FIN_REF]]<Int>([[ARR]])
// CHECK: keypath $KeyPath<SubscriptVariadic1, Int>, (root $SubscriptVariadic1; gettable_property $Int, id @$s8keypaths18SubscriptVariadic1VyS2id_tcig : $@convention(method) (@guaranteed Array<Int>, SubscriptVariadic1) -> Int, getter @$s8keypaths18SubscriptVariadic1VyS2id_tcipACTK : $@convention(thin) (@in_guaranteed SubscriptVariadic1, UnsafeRawPointer) -> @out Int, indices [%$0 : $Array<Int> : $Array<Int>], indices_equals @$sSaySiGTH : $@convention(thin) (UnsafeRawPointer, UnsafeRawPointer) -> Bool, indices_hash @$sSaySiGTh : $@convention(thin) (UnsafeRawPointer) -> Int) ([[FIN_ARR]])
// CHECK: keypath $KeyPath<SubscriptVariadic1, Int>, (root $SubscriptVariadic1; gettable_property $Int, id @$s8keypaths18SubscriptVariadic1VyS2id_tcig : $@convention(method) (@guaranteed Array<Int>, SubscriptVariadic1) -> Int, getter @$s8keypaths18SubscriptVariadic1VyS2id_tcipACTK : $@convention(thin) (@in_guaranteed SubscriptVariadic1, UnsafeRawPointer) -> @out Int, indices [%$0 : $Array<Int> : $Array<Int>], indices_equals @$sSaySiGTH : $@convention(thin) (UnsafeRawPointer, UnsafeRawPointer) -> Bool, indices_hash @$sSaySiGTh : $@convention(thin) (UnsafeRawPointer) -> Int) ([[ARR]])
_ = \SubscriptVariadic1.[]

_ = \SubscriptVariadic2.["", "1"]
Expand Down
4 changes: 1 addition & 3 deletions test/SILGen/scalar_to_tuple_args.swift
Original file line number Diff line number Diff line change
Expand Up @@ -68,8 +68,6 @@ variadicFirst(x)
// CHECK: [[X:%.*]] = load [trivial] [[READ]]
// CHECK: [[ALLOC_ARRAY:%.*]] = apply {{.*}} -> (@owned Array<τ_0_0>, Builtin.RawPointer)
// CHECK: ([[ARRAY:%.*]], [[MEMORY:%.*]]) = destructure_tuple [[ALLOC_ARRAY]]
// CHECK: [[FIN_FN:%.*]] = function_ref @$ss27_finalizeUninitializedArrayySayxGABnlF
// CHECK: [[FIN_ARR:%.*]] = apply [[FIN_FN]]<Int>([[ARRAY]])
// CHECK: [[VARIADIC_SECOND:%.*]] = function_ref @$s20scalar_to_tuple_args14variadicSecondyySi_SidtF
// CHECK: apply [[VARIADIC_SECOND]]([[X]], [[FIN_ARR]])
// CHECK: apply [[VARIADIC_SECOND]]([[X]], [[ARRAY]])
variadicSecond(x)