remove shallowCopy for ARC/ORC (#20070)

* remove shallowCopy for ARC/ORC

* use move

* fix

* more fixes

* typo

* Update lib/system.nim

* follow

* add nodestroy

* move

* copy string

* add a changelog entry

Co-authored-by: xflywind <43030857+xflywind@users.noreply.github.com>
Co-authored-by: Andreas Rumpf <rumpf_a@web.de>
This commit is contained in:
ringabout 2022-07-26 22:51:01 +08:00 • committed by GitHub
commit 4c46358db1
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
10 changed files with 76 additions and 30 deletions

View file

@ -25,6 +25,9 @@
or define your own `Math.trunc` polyfill using the [`emit` pragma](https://nim-lang.org/docs/manual.html#implementation-specific-pragmas-emit-pragma). Nim uses or define your own `Math.trunc` polyfill using the [`emit` pragma](https://nim-lang.org/docs/manual.html#implementation-specific-pragmas-emit-pragma). Nim uses
`Math.trunc` for the division and modulo operators for integers. `Math.trunc` for the division and modulo operators for integers.
- `shallowCopy` is removed for ARC/ORC. Use `move` when possible or combine assignment and
`sink` for optimization purposes.
## Standard library additions and changes ## Standard library additions and changes
[//]: # "Changes:" [//]: # "Changes:"

View file

@ -68,6 +68,9 @@ proc copyHalf[Key, Val](h, result: Node[Key, Val]) =
result.links[j] = h.links[Mhalf + j] result.links[j] = h.links[Mhalf + j]
else: else:
for j in 0..<Mhalf: for j in 0..<Mhalf:
when defined(gcArc) or defined(gcOrc):
result.vals[j] = move h.vals[Mhalf + j]
else:
shallowCopy(result.vals[j], h.vals[Mhalf + j]) shallowCopy(result.vals[j], h.vals[Mhalf + j])
proc split[Key, Val](h: Node[Key, Val]): Node[Key, Val] = proc split[Key, Val](h: Node[Key, Val]): Node[Key, Val] =
@ -88,6 +91,9 @@ proc insert[Key, Val](h: Node[Key, Val], key: Key, val: Val): Node[Key, Val] =
if less(key, h.keys[j]): break if less(key, h.keys[j]): break
inc j inc j
for i in countdown(h.entries, j+1): for i in countdown(h.entries, j+1):
when defined(gcArc) or defined(gcOrc):
h.vals[i] = move h.vals[i-1]
else:
shallowCopy(h.vals[i], h.vals[i-1]) shallowCopy(h.vals[i], h.vals[i-1])
h.vals[j] = val h.vals[j] = val
else: else:

View file

@ -218,10 +218,17 @@ proc setDirtyFile*(conf: ConfigRef; fileIdx: FileIndex; filename: AbsoluteFile)
proc setHash*(conf: ConfigRef; fileIdx: FileIndex; hash: string) = proc setHash*(conf: ConfigRef; fileIdx: FileIndex; hash: string) =
assert fileIdx.int32 >= 0 assert fileIdx.int32 >= 0
when defined(gcArc) or defined(gcOrc):
conf.m.fileInfos[fileIdx.int32].hash = hash
else:
shallowCopy(conf.m.fileInfos[fileIdx.int32].hash, hash) shallowCopy(conf.m.fileInfos[fileIdx.int32].hash, hash)
proc getHash*(conf: ConfigRef; fileIdx: FileIndex): string = proc getHash*(conf: ConfigRef; fileIdx: FileIndex): string =
assert fileIdx.int32 >= 0 assert fileIdx.int32 >= 0
when defined(gcArc) or defined(gcOrc):
result = conf.m.fileInfos[fileIdx.int32].hash
else:
shallowCopy(result, conf.m.fileInfos[fileIdx.int32].hash) shallowCopy(result, conf.m.fileInfos[fileIdx.int32].hash)
proc toFullPathConsiderDirty*(conf: ConfigRef; fileIdx: FileIndex): AbsoluteFile = proc toFullPathConsiderDirty*(conf: ConfigRef; fileIdx: FileIndex): AbsoluteFile =

View file

@ -22,6 +22,9 @@ proc replaceDeprecated*(conf: ConfigRef; info: TLineInfo; oldSym, newSym: PIdent
let last = first+identLen(line, first)-1 let last = first+identLen(line, first)-1
if cmpIgnoreStyle(line[first..last], oldSym.s) == 0: if cmpIgnoreStyle(line[first..last], oldSym.s) == 0:
var x = line.substr(0, first-1) & newSym.s & line.substr(last+1) var x = line.substr(0, first-1) & newSym.s & line.substr(last+1)
when defined(gcArc) or defined(gcOrc):
conf.m.fileInfos[info.fileIndex.int32].lines[info.line.int-1] = move x
else:
system.shallowCopy(conf.m.fileInfos[info.fileIndex.int32].lines[info.line.int-1], x) system.shallowCopy(conf.m.fileInfos[info.fileIndex.int32].lines[info.line.int-1], x)
conf.m.fileInfos[info.fileIndex.int32].dirty = true conf.m.fileInfos[info.fileIndex.int32].dirty = true
#if newSym.s == "File": writeStackTrace() #if newSym.s == "File": writeStackTrace()
@ -35,5 +38,8 @@ proc replaceComment*(conf: ConfigRef; info: TLineInfo) =
if line[first] != '#': inc first if line[first] != '#': inc first
var x = line.substr(0, first-1) & "discard " & line.substr(first+1).escape var x = line.substr(0, first-1) & "discard " & line.substr(first+1).escape
when defined(gcArc) or defined(gcOrc):
conf.m.fileInfos[info.fileIndex.int32].lines[info.line.int-1] = move x
else:
system.shallowCopy(conf.m.fileInfos[info.fileIndex.int32].lines[info.line.int-1], x) system.shallowCopy(conf.m.fileInfos[info.fileIndex.int32].lines[info.line.int-1], x)
conf.m.fileInfos[info.fileIndex.int32].dirty = true conf.m.fileInfos[info.fileIndex.int32].dirty = true

View file

@ -511,6 +511,9 @@ proc processCompile(c: PContext, n: PNode) =
n[i] = c.semConstExpr(c, n[i]) n[i] = c.semConstExpr(c, n[i])
case n[i].kind case n[i].kind
of nkStrLit, nkRStrLit, nkTripleStrLit: of nkStrLit, nkRStrLit, nkTripleStrLit:
when defined(gcArc) or defined(gcOrc):
result = n[i].strVal
else:
shallowCopy(result, n[i].strVal) shallowCopy(result, n[i].strVal)
else: else:
localError(c.config, n.info, errStringLiteralExpected) localError(c.config, n.info, errStringLiteralExpected)

View file

@ -114,8 +114,12 @@ template decodeBx(k: untyped) {.dirty.} =
let rbx = instr.regBx - wordExcess let rbx = instr.regBx - wordExcess
ensureKind(k) ensureKind(k)
template move(a, b: untyped) {.dirty.} = system.shallowCopy(a, b) template move(a, b: untyped) {.dirty.} =
# XXX fix minor 'shallowCopy' overloading bug in compiler when defined(gcArc) or defined(gcOrc):
a = move b
else:
system.shallowCopy(a, b)
# XXX fix minor 'shallowCopy' overloading bug in compiler
proc derefPtrToReg(address: BiggestInt, typ: PType, r: var TFullReg, isAssign: bool): bool = proc derefPtrToReg(address: BiggestInt, typ: PType, r: var TFullReg, isAssign: bool): bool =
# nim bug: `isAssign: static bool` doesn't work, giving odd compiler error # nim bug: `isAssign: static bool` doesn't work, giving odd compiler error

View file

@ -170,7 +170,7 @@ proc processRequest(
server: AsyncHttpServer, server: AsyncHttpServer,
req: FutureVar[Request], req: FutureVar[Request],
client: AsyncSocket, client: AsyncSocket,
address: string, address: sink string,
lineFut: FutureVar[string], lineFut: FutureVar[string],
callback: proc (request: Request): Future[void] {.closure, gcsafe.}, callback: proc (request: Request): Future[void] {.closure, gcsafe.},
): Future[bool] {.async.} = ): Future[bool] {.async.} =
@ -184,6 +184,9 @@ proc processRequest(
# \n # \n
request.headers.clear() request.headers.clear()
request.body = "" request.body = ""
when defined(gcArc) or defined(gcOrc):
request.hostname = address
else:
request.hostname.shallowCopy(address) request.hostname.shallowCopy(address)
assert client != nil assert client != nil
request.client = client request.client = client

View file

@ -288,7 +288,7 @@ proc load*[T](s: Stream, data: var T) =
var tab = initTable[BiggestInt, pointer]() var tab = initTable[BiggestInt, pointer]()
loadAny(s, toAny(data), tab) loadAny(s, toAny(data), tab)
proc store*[T](s: Stream, data: T) = proc store*[T](s: Stream, data: sink T) =
## Stores `data` into the stream `s`. Raises `IOError` in case of an error. ## Stores `data` into the stream `s`. Raises `IOError` in case of an error.
runnableExamples: runnableExamples:
import std/streams import std/streams
@ -301,13 +301,16 @@ proc store*[T](s: Stream, data: T) =
var stored = initIntSet() var stored = initIntSet()
var d: T var d: T
when defined(gcArc) or defined(gcOrc):
d = data
else:
shallowCopy(d, data) shallowCopy(d, data)
storeAny(s, toAny(d), stored) storeAny(s, toAny(d), stored)
proc loadVM[T](typ: typedesc[T], x: T): string = proc loadVM[T](typ: typedesc[T], x: T): string =
discard "the implementation is in the compiler/vmops" discard "the implementation is in the compiler/vmops"
proc `$$`*[T](x: T): string = proc `$$`*[T](x: sink T): string =
## Returns a string representation of `x` (serialization, marshalling). ## Returns a string representation of `x` (serialization, marshalling).
## ##
## **Note:** to serialize `x` to JSON use `%x` from the `json` module ## **Note:** to serialize `x` to JSON use `%x` from the `json` module
@ -327,6 +330,9 @@ proc `$$`*[T](x: T): string =
else: else:
var stored = initIntSet() var stored = initIntSet()
var d: T var d: T
when defined(gcArc) or defined(gcOrc):
d = x
else:
shallowCopy(d, x) shallowCopy(d, x)
var s = newStringStream() var s = newStringStream()
storeAny(s, toAny(d), stored) storeAny(s, toAny(d), stored)

View file

@ -464,7 +464,8 @@ proc low*(x: string): int {.magic: "Low", noSideEffect.}
## var str = "Hello world!" ## var str = "Hello world!"
## low(str) # => 0 ## low(str) # => 0
proc shallowCopy*[T](x: var T, y: T) {.noSideEffect, magic: "ShallowCopy".} when not defined(gcArc) and not defined(gcOrc):
proc shallowCopy*[T](x: var T, y: T) {.noSideEffect, magic: "ShallowCopy".}
## Use this instead of `=` for a `shallow copy`:idx:. ## Use this instead of `=` for a `shallow copy`:idx:.
## ##
## The shallow copy only changes the semantics for sequences and strings ## The shallow copy only changes the semantics for sequences and strings
@ -473,8 +474,6 @@ proc shallowCopy*[T](x: var T, y: T) {.noSideEffect, magic: "ShallowCopy".}
## Be careful with the changed semantics though! ## Be careful with the changed semantics though!
## There is a reason why the default assignment does a deep copy of sequences ## There is a reason why the default assignment does a deep copy of sequences
## and strings. ## and strings.
##
## .. warning:: `shallowCopy` does a deep copy with ARC/ORC.
# :array|openArray|string|seq|cstring|tuple # :array|openArray|string|seq|cstring|tuple
proc `[]`*[I: Ordinal;T](a: T; i: I): T {. proc `[]`*[I: Ordinal;T](a: T; i: I): T {.
@ -492,8 +491,11 @@ proc arrPut[I: Ordinal;T,S](a: T; i: I;
proc `=destroy`*[T](x: var T) {.inline, magic: "Destroy".} = proc `=destroy`*[T](x: var T) {.inline, magic: "Destroy".} =
## Generic `destructor`:idx: implementation that can be overridden. ## Generic `destructor`:idx: implementation that can be overridden.
discard discard
proc `=sink`*[T](x: var T; y: T) {.inline, magic: "Asgn".} = proc `=sink`*[T](x: var T; y: T) {.inline, nodestroy, magic: "Asgn".} =
## Generic `sink`:idx: implementation that can be overridden. ## Generic `sink`:idx: implementation that can be overridden.
when defined(gcArc) or defined(gcOrc):
x = y
else:
shallowCopy(x, y) shallowCopy(x, y)
when defined(nimHasTrace): when defined(nimHasTrace):
@ -2852,6 +2854,9 @@ when hasAlloc or defined(nimscript):
setLen(x, xl+item.len) setLen(x, xl+item.len)
var j = xl-1 var j = xl-1
while j >= i: while j >= i:
when defined(gcArc) or defined(gcOrc):
x[j+item.len] = move x[j]
else:
shallowCopy(x[j+item.len], x[j]) shallowCopy(x[j+item.len], x[j])
dec(j) dec(j)
j = 0 j = 0

View file

@ -9,6 +9,9 @@ type
proc createCycle(leaf: string): Node = proc createCycle(leaf: string): Node =
new result new result
result.a = result result.a = result
when defined(gcArc) or defined(gcOrc):
result.leaf = leaf
else:
shallowCopy result.leaf, leaf shallowCopy result.leaf, leaf
proc main = proc main =