@@ -358,15 +358,37 @@ func (v Value) SetIndex(i int, x interface{}) {
358
358
359
359
func valueSetIndex (v ref , i int , x ref )
360
360
361
- func makeArgs (args []interface {}) ([]Value , []ref ) {
362
- argVals := make ([]Value , len (args ))
363
- argRefs := make ([]ref , len (args ))
361
+ const pooledArgsLength = 16
362
+
363
+ var (
364
+ argRefsPool [][]ref
365
+ argValsPool [][]Value
366
+ )
367
+
368
+ func makeArgs (args []interface {}) (argVals []Value , argRefs []ref ) {
369
+ if len (args ) <= pooledArgsLength && len (argRefsPool ) > 0 {
370
+ last := len (argValsPool ) - 1
371
+ argVals = argValsPool [last ]
372
+ argRefs = argRefsPool [last ]
373
+ argValsPool = argValsPool [:last ]
374
+ argRefsPool = argRefsPool [:last ]
375
+ } else {
376
+ argVals = make ([]Value , pooledArgsLength )
377
+ argRefs = make ([]ref , pooledArgsLength )
378
+ }
379
+ argVals , argRefs = argVals [:len (args )], argRefs [:len (args )]
364
380
for i , arg := range args {
365
381
v := ValueOf (arg )
366
382
argVals [i ] = v
367
383
argRefs [i ] = v .ref
368
384
}
369
- return argVals , argRefs
385
+ return
386
+ }
387
+
388
+ func poolArgs (argVals []Value , argRefs []ref ) {
389
+ // No need to check length, because larger slices are compatible
390
+ argValsPool = append (argValsPool , argVals )
391
+ argRefsPool = append (argRefsPool , argRefs )
370
392
}
371
393
372
394
// Length returns the JavaScript property "length" of v.
@@ -389,7 +411,7 @@ func (v Value) Call(m string, args ...interface{}) Value {
389
411
argVals , argRefs := makeArgs (args )
390
412
res , ok := valueCall (v .ref , m , argRefs )
391
413
runtime .KeepAlive (v )
392
- runtime . KeepAlive (argVals )
414
+ poolArgs (argVals , argRefs )
393
415
if ! ok {
394
416
if vType := v .Type (); ! vType .isObject () { // check here to avoid overhead in success case
395
417
panic (& ValueError {"Value.Call" , vType })
@@ -411,7 +433,7 @@ func (v Value) Invoke(args ...interface{}) Value {
411
433
argVals , argRefs := makeArgs (args )
412
434
res , ok := valueInvoke (v .ref , argRefs )
413
435
runtime .KeepAlive (v )
414
- runtime . KeepAlive (argVals )
436
+ poolArgs (argVals , argRefs )
415
437
if ! ok {
416
438
if vType := v .Type (); vType != TypeFunction { // check here to avoid overhead in success case
417
439
panic (& ValueError {"Value.Invoke" , vType })
@@ -430,7 +452,7 @@ func (v Value) New(args ...interface{}) Value {
430
452
argVals , argRefs := makeArgs (args )
431
453
res , ok := valueNew (v .ref , argRefs )
432
454
runtime .KeepAlive (v )
433
- runtime . KeepAlive (argVals )
455
+ poolArgs (argVals , argRefs )
434
456
if ! ok {
435
457
if vType := v .Type (); vType != TypeFunction { // check here to avoid overhead in success case
436
458
panic (& ValueError {"Value.Invoke" , vType })
0 commit comments