Files
sdk/pkg/dart2bytecode/testcases/invisible.dart.expect
Alexander Markov 51d1c8923a Reland "[vm,dart2bytecode,modular_aot] Variable-length closure objects"
This is a reland of commit 88496ba1c3

Fixes on top of the original change:

* Closure layout is changed to avoid gap between fixed fields and
  variable-length elements on compressed pointers architecture.
  This gap was causing crashes in the GC when scanning closure
  objects.

* pkg/vm_snapshot_analysis/test/instruction_sizes_test is fixed
  on arm64 by decreasing threshold for detecting size changes.

Original change's description:
> [vm,dart2bytecode,modular_aot] Variable-length closure objects
>
> Extend closure objects with variable number of elements to capture.
> This is needed to support capturing multiple independent contexts
> after capturing is computed in the front-end.
>
> The following fixed Closure fields are moved into variable-length
> elements:
>  - delayed type arguments;
>  - instantiator type arguments;
>  - function type arguments;
>  - context.
>
> Number of elements and presence/indices of various type arguments
> are encoded into the new length_and_flags field in the Closure.
>
> Most closure objects don't need any of the type arguments so this
> change will reduce average Closure object size.

TEST=ci
Issue: https://github.com/dart-lang/sdk/issues/61572
Issue: https://github.com/dart-lang/sdk/issues/61635

Change-Id: I8685e632e2d0832766ecdc470f3cf9a6b880de48
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/494243
Commit-Queue: Alexander Markov <alexmarkov@google.com>
Reviewed-by: Tess Strickland <sstrickl@google.com>
Reviewed-by: Slava Egorov <vegorov@google.com>
2026-04-10 06:15:22 -07:00

255 lines
6.9 KiB
Plaintext

Bytecode
Dynamic Module Entry Point: DART_SDK/pkg/dart2bytecode/testcases/invisible.dart::main
Library 'DART_SDK/pkg/dart2bytecode/testcases/invisible.dart'
name '#lib'
script 'DART_SDK/pkg/dart2bytecode/testcases/invisible.dart'
Class '', script = 'DART_SDK/pkg/dart2bytecode/testcases/invisible.dart'
Function 'visible', static, reflectable, debuggable
parameters [FunctionType () -> void 'fun'] (required: 1)
return-type void
Bytecode {
Entry 1
CheckStack 0
PushConstant CP#0
DirectCall CP#1, 1
Drop1
Push FP[-5]
StoreLocal r0
Push r0
UncheckedClosureCall CP#3, 1
Drop1
PushNull
ReturnTOS
}
ConstantPool {
[0] = ObjectRef 'visible()'
[1] = DirectCall 'dart:core::print', ArgDesc num-args 1, num-type-args 0, names []
[2] = Reserved
[3] = ObjectRef ArgDesc num-args 1, num-type-args 0, names []
}
Function 'invisible', static, reflectable, debuggable, invisible, has-pragma
parameters [FunctionType () -> void 'fun'] (required: 1)
return-type void
annotations const List<dynamic> [const dart:core::pragma {dart:core::pragma::name (field): 'vm:invisible', dart:core::pragma::options (field): null}]
Bytecode {
Entry 1
CheckStack 0
PushConstant CP#0
DirectCall CP#1, 1
Drop1
Push FP[-5]
StoreLocal r0
Push r0
UncheckedClosureCall CP#3, 1
Drop1
PushNull
ReturnTOS
}
ConstantPool {
[0] = ObjectRef 'invisible()'
[1] = DirectCall 'dart:core::print', ArgDesc num-args 1, num-type-args 0, names []
[2] = Reserved
[3] = ObjectRef ArgDesc num-args 1, num-type-args 0, names []
}
Function 'visibleClosure', static, reflectable, debuggable
parameters [FunctionType () -> void 'fun'] (required: 1)
return-type void
Bytecode {
Entry 4
CheckStack 0
AllocateContext 0, 1
PopLocal r0
Push r0
Push FP[-5]
StoreContextVar 0, 0
AllocateClosure CP#6
StoreLocal r3
Push r3
Push r0
StoreClosureElement 0
PopLocal r2
Push r2
Push r2
UncheckedClosureCall CP#4, 1
Drop1
PushNull
ReturnTOS
}
ConstantPool {
[0] = ClosureFunction 0
[1] = ObjectRef 'visibleInner'
[2] = DirectCall 'dart:core::print', ArgDesc num-args 1, num-type-args 0, names []
[3] = Reserved
[4] = ObjectRef ArgDesc num-args 1, num-type-args 0, names []
[5] = EndClosureFunctionScope
[6] = AllocateClosure 0, num-elements: 1, flags: 0
[7] = Reserved
}
Closure DART_SDK/pkg/dart2bytecode/testcases/invisible.dart::visibleClosure::'visibleInner' () -> Null
ClosureCode {
Entry 3
Push FP[-5]
LoadClosureElement 0
PopLocal r0
CheckStack 0
PushConstant CP#1
DirectCall CP#2, 1
Drop1
Push r0
LoadContextVar 0, 0
StoreLocal r2
Push r2
UncheckedClosureCall CP#4, 1
Drop1
PushNull
ReturnTOS
}
Function 'invisibleClosure', static, reflectable, debuggable
parameters [FunctionType () -> void 'fun'] (required: 1)
return-type void
Bytecode {
Entry 4
CheckStack 0
AllocateContext 0, 1
PopLocal r0
Push r0
Push FP[-5]
StoreContextVar 0, 0
AllocateClosure CP#6
StoreLocal r3
Push r3
Push r0
StoreClosureElement 0
PopLocal r2
Push r2
Push r2
UncheckedClosureCall CP#4, 1
Drop1
PushNull
ReturnTOS
}
ConstantPool {
[0] = ClosureFunction 0
[1] = ObjectRef 'invisibleInner'
[2] = DirectCall 'dart:core::print', ArgDesc num-args 1, num-type-args 0, names []
[3] = Reserved
[4] = ObjectRef ArgDesc num-args 1, num-type-args 0, names []
[5] = EndClosureFunctionScope
[6] = AllocateClosure 0, num-elements: 1, flags: 0
[7] = Reserved
}
Closure DART_SDK/pkg/dart2bytecode/testcases/invisible.dart::invisibleClosure::'invisibleInner' invisible annotations const List<dynamic> [const dart:core::pragma {dart:core::pragma::name (field): 'vm:invisible', dart:core::pragma::options (field): null}]
() -> Null
ClosureCode {
Entry 3
Push FP[-5]
LoadClosureElement 0
PopLocal r0
CheckStack 0
PushConstant CP#1
DirectCall CP#2, 1
Drop1
Push r0
LoadContextVar 0, 0
StoreLocal r2
Push r2
UncheckedClosureCall CP#4, 1
Drop1
PushNull
ReturnTOS
}
Function 'main', static, reflectable, debuggable
parameters [] (required: 0)
return-type dynamic
Bytecode {
Entry 0
CheckStack 0
PushNull
ReturnTOS
}
ConstantPool {
}
Class 'A', script = 'DART_SDK/pkg/dart2bytecode/testcases/invisible.dart'
extends dart:core::Object
Function 'visible', constructor, reflectable, debuggable
parameters [FunctionType () -> void 'fun'] (required: 1)
return-type DART_SDK/pkg/dart2bytecode/testcases/invisible.dart::A
Bytecode {
Entry 1
CheckStack 0
Push FP[-6]
DirectCall CP#0, 1
Drop1
PushConstant CP#2
DirectCall CP#3, 1
Drop1
Push FP[-5]
StoreLocal r0
Push r0
UncheckedClosureCall CP#5, 1
Drop1
PushNull
ReturnTOS
}
ConstantPool {
[0] = DirectCall 'dart:core::Object:: (constructor)', ArgDesc num-args 1, num-type-args 0, names []
[1] = Reserved
[2] = ObjectRef 'A.visible'
[3] = DirectCall 'dart:core::print', ArgDesc num-args 1, num-type-args 0, names []
[4] = Reserved
[5] = ObjectRef ArgDesc num-args 1, num-type-args 0, names []
}
Function 'invisible', constructor, reflectable, debuggable, invisible, has-pragma
parameters [FunctionType () -> void 'fun'] (required: 1)
return-type DART_SDK/pkg/dart2bytecode/testcases/invisible.dart::A
annotations const List<dynamic> [const dart:core::pragma {dart:core::pragma::name (field): 'vm:invisible', dart:core::pragma::options (field): null}]
Bytecode {
Entry 1
CheckStack 0
Push FP[-6]
DirectCall CP#0, 1
Drop1
PushConstant CP#2
DirectCall CP#3, 1
Drop1
Push FP[-5]
StoreLocal r0
Push r0
UncheckedClosureCall CP#5, 1
Drop1
PushNull
ReturnTOS
}
ConstantPool {
[0] = DirectCall 'dart:core::Object:: (constructor)', ArgDesc num-args 1, num-type-args 0, names []
[1] = Reserved
[2] = ObjectRef 'A.invisible'
[3] = DirectCall 'dart:core::print', ArgDesc num-args 1, num-type-args 0, names []
[4] = Reserved
[5] = ObjectRef ArgDesc num-args 1, num-type-args 0, names []
}