diff --git a/pkg/vm/bin/kernel_service.dart b/pkg/vm/bin/kernel_service.dart index 778ccc08c9b..fb5d3f15a69 100644 --- a/pkg/vm/bin/kernel_service.dart +++ b/pkg/vm/bin/kernel_service.dart @@ -732,10 +732,10 @@ Future _processLoadRequest(request) async { final bool enableAsserts = request[9]; final List experimentalFlags = request[10] != null ? request[10].cast() : null; - final String packageConfig = request[12]; - final String multirootFilepaths = request[13]; - final String multirootScheme = request[14]; - final String workingDirectory = request[15]; + final String packageConfig = request[11]; + final String multirootFilepaths = request[12]; + final String multirootScheme = request[13]; + final String workingDirectory = request[14]; Uri platformKernelPath = null; List platformKernel = null; @@ -981,7 +981,6 @@ Future trainInternal(String scriptUri, String platformKernelPath) async { false /* suppress warnings */, false /* enable asserts */, null /* experimental_flags */, - null /* unused */, null /* package_config */, null /* multirootFilepaths */, null /* multirootScheme */, diff --git a/runtime/bin/gen_snapshot.cc b/runtime/bin/gen_snapshot.cc index 9f014ddd992..72e10c866b9 100644 --- a/runtime/bin/gen_snapshot.cc +++ b/runtime/bin/gen_snapshot.cc @@ -125,7 +125,6 @@ static const char* kSnapshotKindNames[] = { V(compile_all, compile_all) \ V(help, help) \ V(obfuscate, obfuscate) \ - V(read_all_bytecode, read_all_bytecode) \ V(strip, strip) \ V(verbose, verbose) \ V(version, version) @@ -390,13 +389,6 @@ static void MaybeLoadExtraInputs(const CommandLineOptions& inputs) { } static void MaybeLoadCode() { - if (read_all_bytecode && - ((snapshot_kind == kCore) || (snapshot_kind == kCoreJIT) || - (snapshot_kind == kApp) || (snapshot_kind == kAppJIT))) { - Dart_Handle result = Dart_ReadAllBytecode(); - CHECK_RESULT(result); - } - if (compile_all && ((snapshot_kind == kCoreJIT) || (snapshot_kind == kAppJIT))) { Dart_Handle result = Dart_CompileAll(); diff --git a/runtime/include/dart_native_api.h b/runtime/include/dart_native_api.h index 495d4548566..7aeb40dd2ff 100644 --- a/runtime/include/dart_native_api.h +++ b/runtime/include/dart_native_api.h @@ -178,8 +178,6 @@ DART_EXPORT bool Dart_CloseNativePort(Dart_Port native_port_id); */ DART_EXPORT DART_WARN_UNUSED_RESULT Dart_Handle Dart_CompileAll(); -DART_EXPORT DART_WARN_UNUSED_RESULT Dart_Handle Dart_ReadAllBytecode(); - /** * Finalizes all classes. */ diff --git a/runtime/lib/errors.cc b/runtime/lib/errors.cc index 7106518b756..cce88cf68fd 100644 --- a/runtime/lib/errors.cc +++ b/runtime/lib/errors.cc @@ -31,25 +31,21 @@ static ScriptPtr FindScript(DartFrameIterator* iterator) { ASSERT(!assert_error_class.IsNull()); bool hit_assertion_error = false; for (; stack_frame != NULL; stack_frame = iterator->NextFrame()) { - if (stack_frame->is_interpreted()) { - func = stack_frame->LookupDartFunction(); - } else { - code = stack_frame->LookupDartCode(); - if (code.is_optimized()) { - InlinedFunctionsIterator inlined_iterator(code, stack_frame->pc()); - while (!inlined_iterator.Done()) { - func = inlined_iterator.function(); - if (hit_assertion_error) { - return func.script(); - } - ASSERT(!hit_assertion_error); - hit_assertion_error = (func.Owner() == assert_error_class.raw()); - inlined_iterator.Advance(); + code = stack_frame->LookupDartCode(); + if (code.is_optimized()) { + InlinedFunctionsIterator inlined_iterator(code, stack_frame->pc()); + while (!inlined_iterator.Done()) { + func = inlined_iterator.function(); + if (hit_assertion_error) { + return func.script(); } - continue; - } else { - func = code.function(); + ASSERT(!hit_assertion_error); + hit_assertion_error = (func.Owner() == assert_error_class.raw()); + inlined_iterator.Advance(); } + continue; + } else { + func = code.function(); } ASSERT(!func.IsNull()); if (hit_assertion_error) { diff --git a/runtime/lib/ffi.cc b/runtime/lib/ffi.cc index 3c4a07cbc2f..b514b86d4a4 100644 --- a/runtime/lib/ffi.cc +++ b/runtime/lib/ffi.cc @@ -306,36 +306,9 @@ DEFINE_NATIVE_ENTRY(Ffi_sizeOf, 1, 0) { return Integer::New(SizeOf(type_arg, zone)); } -// Static invocations to this method are translated directly in streaming FGB -// and bytecode FGB. However, we can still reach this entrypoint in the bytecode -// interpreter. +// Static invocations to this method are translated directly in streaming FGB. DEFINE_NATIVE_ENTRY(Ffi_asFunctionInternal, 2, 1) { -#if defined(DART_PRECOMPILED_RUNTIME) || defined(DART_PRECOMPILER) UNREACHABLE(); -#else - ASSERT(FLAG_enable_interpreter); - - GET_NON_NULL_NATIVE_ARGUMENT(Pointer, pointer, arguments->NativeArgAt(0)); - GET_NATIVE_TYPE_ARGUMENT(dart_type, arguments->NativeTypeArgAt(0)); - GET_NATIVE_TYPE_ARGUMENT(native_type, arguments->NativeTypeArgAt(1)); - - const Function& dart_signature = - Function::Handle(zone, Type::Cast(dart_type).signature()); - const Function& native_signature = - Function::Handle(zone, Type::Cast(native_type).signature()); - const Function& function = Function::Handle( - compiler::ffi::TrampolineFunction(dart_signature, native_signature)); - - // Set the c function pointer in the context of the closure rather than in - // the function so that we can reuse the function for each c function with - // the same signature. - const Context& context = Context::Handle(Context::New(1)); - context.SetAt(0, pointer); - - return Closure::New(Object::null_type_arguments(), - Object::null_type_arguments(), function, context, - Heap::kOld); -#endif } DEFINE_NATIVE_ENTRY(Ffi_asExternalTypedData, 0, 2) { diff --git a/runtime/lib/mirrors.cc b/runtime/lib/mirrors.cc index 458e9a18389..e1ab1400223 100644 --- a/runtime/lib/mirrors.cc +++ b/runtime/lib/mirrors.cc @@ -456,76 +456,6 @@ static InstancePtr CreateLibraryDependencyMirror(Thread* thread, prefix_name, is_import, is_deferred); } -static GrowableObjectArrayPtr CreateBytecodeLibraryDependencies( - Thread* thread, - const Library& lib, - const Instance& lib_mirror) { - ASSERT(lib.is_declared_in_bytecode()); - - // Make sure top level class (containing annotations) is fully loaded. - lib.EnsureTopLevelClassIsFinalized(); - - const auto& deps = GrowableObjectArray::Handle(GrowableObjectArray::New()); - Array& metadata = Array::Handle(lib.GetExtendedMetadata(lib, 1)); - if (metadata.Length() == 0) { - return deps.raw(); - } - - // Library has the only element in the extended metadata. - metadata ^= metadata.At(0); - if (metadata.IsNull()) { - return deps.raw(); - } - - auto& desc = Array::Handle(); - auto& target_uri = String::Handle(); - auto& importee = Library::Handle(); - auto& is_export = Bool::Handle(); - auto& is_deferred = Bool::Handle(); - auto& prefix_name = String::Handle(); - auto& show_names = Array::Handle(); - auto& hide_names = Array::Handle(); - auto& dep_metadata = Instance::Handle(); - auto& dep = Instance::Handle(); - const auto& no_prefix = LibraryPrefix::Handle(); - - for (intptr_t i = 0, n = metadata.Length(); i < n; ++i) { - desc ^= metadata.At(i); - // Each dependency is represented as an array with the following layout: - // [0] = target library URI (String) - // [1] = is_export (bool) - // [2] = is_deferred (bool) - // [3] = prefix (String or null) - // [4] = list of show names (List) - // [5] = list of hide names (List) - // [6] = annotations - // The library dependencies are encoded by getLibraryAnnotations(), - // pkg/vm/lib/bytecode/gen_bytecode.dart. - target_uri ^= desc.At(0); - is_export ^= desc.At(1); - is_deferred ^= desc.At(2); - prefix_name ^= desc.At(3); - show_names ^= desc.At(4); - hide_names ^= desc.At(5); - dep_metadata ^= desc.At(6); - - importee = Library::LookupLibrary(thread, target_uri); - if (importee.IsNull()) { - continue; - } - ASSERT(importee.Loaded()); - - dep = CreateLibraryDependencyMirror( - thread, lib_mirror, importee, show_names, hide_names, dep_metadata, - no_prefix, prefix_name, !is_export.value(), is_deferred.value()); - if (!dep.IsNull()) { - deps.Add(dep); - } - } - - return deps.raw(); -} - DEFINE_NATIVE_ENTRY(LibraryMirror_fromPrefix, 0, 1) { GET_NON_NULL_NATIVE_ARGUMENT(LibraryPrefix, prefix, arguments->NativeArgAt(0)); @@ -541,10 +471,6 @@ DEFINE_NATIVE_ENTRY(LibraryMirror_libraryDependencies, 0, 2) { GET_NON_NULL_NATIVE_ARGUMENT(MirrorReference, ref, arguments->NativeArgAt(1)); const Library& lib = Library::Handle(ref.GetLibraryReferent()); - if (lib.is_declared_in_bytecode()) { - return CreateBytecodeLibraryDependencies(thread, lib, lib_mirror); - } - Array& ports = Array::Handle(); Namespace& ns = Namespace::Handle(); Instance& dep = Instance::Handle(); diff --git a/runtime/lib/stacktrace.cc b/runtime/lib/stacktrace.cc index c2d8657fab4..43383d4adeb 100644 --- a/runtime/lib/stacktrace.cc +++ b/runtime/lib/stacktrace.cc @@ -141,7 +141,7 @@ DEFINE_NATIVE_ENTRY(StackTrace_asyncStackTraceHelper, 0, 1) { if (!FLAG_causal_async_stacks) { // If causal async stacks are not enabled we should recognize this method // and never call to the NOP runtime. - // See kernel_to_il.cc/bytecode_reader.cc/interpreter.cc. + // See kernel_to_il.cc. UNREACHABLE(); } #if !defined(PRODUCT) @@ -180,7 +180,6 @@ static void AppendFrames(const GrowableObjectArray& code_list, StackFrame* frame = frames.NextFrame(); ASSERT(frame != NULL); // We expect to find a dart invocation frame. Code& code = Code::Handle(zone); - Bytecode& bytecode = Bytecode::Handle(zone); Smi& offset = Smi::Handle(zone); for (; frame != NULL; frame = frames.NextFrame()) { if (!frame->IsDartFrame()) { @@ -191,18 +190,9 @@ static void AppendFrames(const GrowableObjectArray& code_list, continue; } - if (frame->is_interpreted()) { - bytecode = frame->LookupDartBytecode(); - if (bytecode.function() == Function::null()) { - continue; - } - offset = Smi::New(frame->pc() - bytecode.PayloadStart()); - code_list.Add(bytecode); - } else { - code = frame->LookupDartCode(); - offset = Smi::New(frame->pc() - code.PayloadStart()); - code_list.Add(code); - } + code = frame->LookupDartCode(); + offset = Smi::New(frame->pc() - code.PayloadStart()); + code_list.Add(code); pc_offset_list.Add(offset); } } diff --git a/runtime/lib/typed_data.cc b/runtime/lib/typed_data.cc index b49b14eca97..d71d08eee86 100644 --- a/runtime/lib/typed_data.cc +++ b/runtime/lib/typed_data.cc @@ -178,7 +178,7 @@ DEFINE_NATIVE_ENTRY(TypedData_setRange, 0, 7) { } // Native methods for typed data allocation are recognized and implemented -// both in FlowGraphBuilder::BuildGraphOfRecognizedMethod and interpreter. +// in FlowGraphBuilder::BuildGraphOfRecognizedMethod. // These bodies exist only to assert that they are not used. #define TYPED_DATA_NEW(name) \ DEFINE_NATIVE_ENTRY(TypedData_##name##_new, 0, 2) { \ diff --git a/runtime/observatory/lib/src/elements/function_view.dart b/runtime/observatory/lib/src/elements/function_view.dart index e5bcfd1d957..b1b365438a9 100644 --- a/runtime/observatory/lib/src/elements/function_view.dart +++ b/runtime/observatory/lib/src/elements/function_view.dart @@ -277,21 +277,6 @@ class FunctionViewElement extends CustomElement implements Renderable { ] ]); } - if (_function.bytecode != null) { - members.add(new DivElement() - ..classes = ['memberItem'] - ..children = [ - new DivElement() - ..classes = ['memberName'] - ..text = 'bytecode', - new DivElement() - ..classes = ['memberName'] - ..children = [ - new CodeRefElement(_isolate, _function.bytecode!, queue: _r.queue) - .element, - ] - ]); - } members.add(new DivElement() ..classes = ['memberItem'] ..text = ' '); diff --git a/runtime/observatory/lib/src/models/objects/function.dart b/runtime/observatory/lib/src/models/objects/function.dart index 3dbe6535f41..e63ef40d530 100644 --- a/runtime/observatory/lib/src/models/objects/function.dart +++ b/runtime/observatory/lib/src/models/objects/function.dart @@ -87,9 +87,6 @@ abstract class ServiceFunction extends Object implements FunctionRef { /// [optional] CodeRef? get unoptimizedCode; - /// [optional] - CodeRef? get bytecode; - /// [optional] FieldRef? get field; int? get usageCounter; diff --git a/runtime/observatory/lib/src/service/object.dart b/runtime/observatory/lib/src/service/object.dart index 7215ef72d38..4f9ead00f2e 100644 --- a/runtime/observatory/lib/src/service/object.dart +++ b/runtime/observatory/lib/src/service/object.dart @@ -3165,7 +3165,6 @@ class ServiceFunction extends HeapObject implements M.ServiceFunction { SourceLocation? location; Code? code; Code? unoptimizedCode; - Code? bytecode; bool? isOptimizable; bool? isInlinable; bool? hasIntrinsic; @@ -3224,7 +3223,6 @@ class ServiceFunction extends HeapObject implements M.ServiceFunction { isInlinable = map['_inlinable']; isRecognized = map['_recognized']; unoptimizedCode = map['_unoptimizedCode']; - bytecode = map['_bytecode']; deoptimizations = map['_deoptimizations']; usageCounter = map['_usageCounter']; icDataArray = map['_icDataArray']; diff --git a/runtime/observatory/tests/service/service_test_common.dart b/runtime/observatory/tests/service/service_test_common.dart index e127bde8cc7..01895403909 100644 --- a/runtime/observatory/tests/service/service_test_common.dart +++ b/runtime/observatory/tests/service/service_test_common.dart @@ -577,7 +577,7 @@ IsolateTest checkRecordedStops( expectedStops = removeAdjacentDuplicates(expectedStops); } - // Single stepping in interpreted bytecode may record extra stops. + // Single stepping may record extra stops. // Allow the extra ones as long as the expected ones are recorded. int i = 0; int j = 0; diff --git a/runtime/observatory_2/lib/src/elements/function_view.dart b/runtime/observatory_2/lib/src/elements/function_view.dart index 7077bc3af56..cad9250985a 100644 --- a/runtime/observatory_2/lib/src/elements/function_view.dart +++ b/runtime/observatory_2/lib/src/elements/function_view.dart @@ -276,21 +276,6 @@ class FunctionViewElement extends CustomElement implements Renderable { ] ]); } - if (_function.bytecode != null) { - members.add(new DivElement() - ..classes = ['memberItem'] - ..children = [ - new DivElement() - ..classes = ['memberName'] - ..text = 'bytecode', - new DivElement() - ..classes = ['memberName'] - ..children = [ - new CodeRefElement(_isolate, _function.bytecode, queue: _r.queue) - .element, - ] - ]); - } members.add(new DivElement() ..classes = ['memberItem'] ..text = ' '); diff --git a/runtime/observatory_2/lib/src/models/objects/function.dart b/runtime/observatory_2/lib/src/models/objects/function.dart index 82d3d7f5516..7de7ad607ab 100644 --- a/runtime/observatory_2/lib/src/models/objects/function.dart +++ b/runtime/observatory_2/lib/src/models/objects/function.dart @@ -87,9 +87,6 @@ abstract class ServiceFunction extends Object implements FunctionRef { /// [optional] CodeRef get unoptimizedCode; - /// [optional] - CodeRef get bytecode; - /// [optional] FieldRef get field; int get usageCounter; diff --git a/runtime/observatory_2/lib/src/service/object.dart b/runtime/observatory_2/lib/src/service/object.dart index 046513de563..1bd33fbce1b 100644 --- a/runtime/observatory_2/lib/src/service/object.dart +++ b/runtime/observatory_2/lib/src/service/object.dart @@ -3178,7 +3178,6 @@ class ServiceFunction extends HeapObject implements M.ServiceFunction { SourceLocation location; Code code; Code unoptimizedCode; - Code bytecode; bool isOptimizable; bool isInlinable; bool hasIntrinsic; @@ -3237,7 +3236,6 @@ class ServiceFunction extends HeapObject implements M.ServiceFunction { isInlinable = map['_inlinable']; isRecognized = map['_recognized']; unoptimizedCode = map['_unoptimizedCode']; - bytecode = map['_bytecode']; deoptimizations = map['_deoptimizations']; usageCounter = map['_usageCounter']; icDataArray = map['_icDataArray']; diff --git a/runtime/observatory_2/tests/service_2/service_test_common.dart b/runtime/observatory_2/tests/service_2/service_test_common.dart index 4373982811f..7775b29a996 100644 --- a/runtime/observatory_2/tests/service_2/service_test_common.dart +++ b/runtime/observatory_2/tests/service_2/service_test_common.dart @@ -577,7 +577,7 @@ IsolateTest checkRecordedStops( expectedStops = removeAdjacentDuplicates(expectedStops); } - // Single stepping in interpreted bytecode may record extra stops. + // Single stepping may record extra stops. // Allow the extra ones as long as the expected ones are recorded. int i = 0; int j = 0; diff --git a/runtime/tests/vm/dart/entrypoints/common.dart b/runtime/tests/vm/dart/entrypoints/common.dart index 0d41ddcbd4e..af25c8beac6 100644 --- a/runtime/tests/vm/dart/entrypoints/common.dart +++ b/runtime/tests/vm/dart/entrypoints/common.dart @@ -28,7 +28,7 @@ class TargetCalls { int unchecked = 0; // Leave a little room for some cases which always use the checked entry, like - // lazy compile stub or interpreter warm-up. + // lazy compile stub. static const int wiggle = 10; void expectChecked(int iterations) { diff --git a/runtime/tests/vm/dart/regress_merge_blocks_with_phis_test.dart b/runtime/tests/vm/dart/regress_merge_blocks_with_phis_test.dart deleted file mode 100644 index 606e4c50e96..00000000000 --- a/runtime/tests/vm/dart/regress_merge_blocks_with_phis_test.dart +++ /dev/null @@ -1,35 +0,0 @@ -// Copyright (c) 2019, the Dart project authors. Please see the AUTHORS file -// for details. All rights reserved. Use of this source code is governed by a -// BSD-style license that can be found in the LICENSE file. -// -// VMOptions=--optimization-counter-threshold=5 --use-bytecode-compiler -// -// Test that block merging takes phis into account. -// -// The problem only reproduces with bytecode compiler (--use-bytecode-compiler) -// as bytecode doesn't have backward branches for the redundant loops. -// OSR handling code inserts Phi instructions to JoinEntry -// even when there is only one predecessor. This results in a flow graph -// suitable for block merging with a successor block containing Phi. - -import 'package:expect/expect.dart'; - -void testBottomUpInference() { - Expect.type>([for (; false;) 1]); - Expect.type>([for (; false;) 1]); - Expect.type>([for (; false;) 1]); - Expect.type>([for (; false;) 1]); - Expect.type>([for (; false;) 1]); - Expect.type>([for (; false;) 1]); - Expect.type>([for (; false;) 1]); - Expect.type>([for (; false;) 1]); - Expect.type>([for (; false;) 1]); - Expect.type>([for (; false;) 1]); - Expect.type>([for (; false;) 1]); - Expect.type>([for (; false;) 1]); - Expect.type>([for (; false;) 1]); -} - -main() { - testBottomUpInference(); -} diff --git a/runtime/tests/vm/dart_2/entrypoints/common.dart b/runtime/tests/vm/dart_2/entrypoints/common.dart index bc8822ac79a..19c01b4ea1f 100644 --- a/runtime/tests/vm/dart_2/entrypoints/common.dart +++ b/runtime/tests/vm/dart_2/entrypoints/common.dart @@ -28,7 +28,7 @@ class TargetCalls { int unchecked = 0; // Leave a little room for some cases which always use the checked entry, like - // lazy compile stub or interpreter warm-up. + // lazy compile stub. static const int wiggle = 10; void expectChecked(int iterations) { diff --git a/runtime/tests/vm/dart_2/regress_merge_blocks_with_phis_test.dart b/runtime/tests/vm/dart_2/regress_merge_blocks_with_phis_test.dart deleted file mode 100644 index 606e4c50e96..00000000000 --- a/runtime/tests/vm/dart_2/regress_merge_blocks_with_phis_test.dart +++ /dev/null @@ -1,35 +0,0 @@ -// Copyright (c) 2019, the Dart project authors. Please see the AUTHORS file -// for details. All rights reserved. Use of this source code is governed by a -// BSD-style license that can be found in the LICENSE file. -// -// VMOptions=--optimization-counter-threshold=5 --use-bytecode-compiler -// -// Test that block merging takes phis into account. -// -// The problem only reproduces with bytecode compiler (--use-bytecode-compiler) -// as bytecode doesn't have backward branches for the redundant loops. -// OSR handling code inserts Phi instructions to JoinEntry -// even when there is only one predecessor. This results in a flow graph -// suitable for block merging with a successor block containing Phi. - -import 'package:expect/expect.dart'; - -void testBottomUpInference() { - Expect.type>([for (; false;) 1]); - Expect.type>([for (; false;) 1]); - Expect.type>([for (; false;) 1]); - Expect.type>([for (; false;) 1]); - Expect.type>([for (; false;) 1]); - Expect.type>([for (; false;) 1]); - Expect.type>([for (; false;) 1]); - Expect.type>([for (; false;) 1]); - Expect.type>([for (; false;) 1]); - Expect.type>([for (; false;) 1]); - Expect.type>([for (; false;) 1]); - Expect.type>([for (; false;) 1]); - Expect.type>([for (; false;) 1]); -} - -main() { - testBottomUpInference(); -} diff --git a/runtime/vm/benchmark_test.cc b/runtime/vm/benchmark_test.cc index 28584889951..551ca97b0d9 100644 --- a/runtime/vm/benchmark_test.cc +++ b/runtime/vm/benchmark_test.cc @@ -313,7 +313,6 @@ static void StackFrame_accessFrame(Dart_NativeArguments args) { TransitionNativeToVM transition(thread); const int kNumIterations = 100; Code& code = Code::Handle(thread->zone()); - Bytecode& bytecode = Bytecode::Handle(thread->zone()); for (int i = 0; i < kNumIterations; i++) { StackFrameIterator frames(ValidationPolicy::kDontValidateFrames, thread, StackFrameIterator::kNoCrossThreadIteration); @@ -323,13 +322,8 @@ static void StackFrame_accessFrame(Dart_NativeArguments args) { code = frame->LookupDartCode(); EXPECT(code.function() == Function::null()); } else if (frame->IsDartFrame()) { - if (frame->is_interpreted()) { - bytecode = frame->LookupDartBytecode(); - EXPECT(bytecode.function() != Function::null()); - } else { - code = frame->LookupDartCode(); - EXPECT(code.function() != Function::null()); - } + code = frame->LookupDartCode(); + EXPECT(code.function() != Function::null()); } frame = frames.NextFrame(); } diff --git a/runtime/vm/class_finalizer.cc b/runtime/vm/class_finalizer.cc index 5930f2f9a0c..bd07103d1e2 100644 --- a/runtime/vm/class_finalizer.cc +++ b/runtime/vm/class_finalizer.cc @@ -12,7 +12,6 @@ #include "vm/flags.h" #include "vm/hash_table.h" #include "vm/heap/heap.h" -#include "vm/interpreter.h" #include "vm/isolate.h" #include "vm/kernel_loader.h" #include "vm/log.h" @@ -198,19 +197,14 @@ bool ClassFinalizer::ProcessPendingClasses() { #if defined(DEBUG) for (intptr_t i = 0; i < class_array.Length(); i++) { cls ^= class_array.At(i); - ASSERT(cls.is_declared_in_bytecode() || cls.is_declaration_loaded()); + ASSERT(cls.is_declaration_loaded()); } #endif // Finalize types in all classes. for (intptr_t i = 0; i < class_array.Length(); i++) { cls ^= class_array.At(i); - if (cls.is_declared_in_bytecode()) { - cls.EnsureDeclarationLoaded(); - ASSERT(cls.is_type_finalized()); - } else { - FinalizeTypesInClass(cls); - } + FinalizeTypesInClass(cls); } // Clear pending classes array. @@ -1118,14 +1112,9 @@ void ClassFinalizer::FinalizeClass(const Class& cls) { #if !defined(DART_PRECOMPILED_RUNTIME) // If loading from a kernel, make sure that the class is fully loaded. - ASSERT(cls.IsTopLevel() || cls.is_declared_in_bytecode() || - (cls.kernel_offset() > 0)); + ASSERT(cls.IsTopLevel() || (cls.kernel_offset() > 0)); if (!cls.is_loaded()) { - if (cls.is_declared_in_bytecode()) { - kernel::BytecodeReader::FinishClassLoading(cls); - } else { - kernel::KernelLoader::FinishLoading(cls); - } + kernel::KernelLoader::FinishLoading(cls); if (cls.is_finalized()) { return; } @@ -1264,7 +1253,7 @@ void ClassFinalizer::AllocateEnumValues(const Class& enum_cls) { ASSERT(!sentinel.IsNull()); sentinel.SetStaticValue(enum_value, true); - ASSERT(enum_cls.is_declared_in_bytecode() || enum_cls.kernel_offset() > 0); + ASSERT(enum_cls.kernel_offset() > 0); Error& error = Error::Handle(zone); for (intptr_t i = 0; i < fields.Length(); i++) { field = Field::RawCast(fields.At(i)); @@ -1712,14 +1701,6 @@ void ClassFinalizer::ClearAllCode(bool including_nonchanging_cids) { #ifdef DART_PRECOMPILED_RUNTIME UNREACHABLE(); #else - Thread* mutator_thread = Isolate::Current()->mutator_thread(); - if (mutator_thread != nullptr) { - Interpreter* interpreter = mutator_thread->interpreter(); - if (interpreter != nullptr) { - interpreter->ClearLookupCache(); - } - } - auto const thread = Thread::Current(); auto const isolate = thread->isolate(); StackZone stack_zone(thread); @@ -1730,7 +1711,6 @@ void ClassFinalizer::ClearAllCode(bool including_nonchanging_cids) { public: ClearCodeVisitor(Zone* zone, bool force) : force_(force), - bytecode_(Bytecode::Handle(zone)), pool_(ObjectPool::Handle(zone)), entry_(Object::Handle(zone)) {} @@ -1741,28 +1721,12 @@ void ClassFinalizer::ClearAllCode(bool including_nonchanging_cids) { } void VisitFunction(const Function& function) { - bytecode_ = function.bytecode(); - if (!bytecode_.IsNull()) { - pool_ = bytecode_.object_pool(); - for (intptr_t i = 0; i < pool_.Length(); i++) { - ObjectPool::EntryType entry_type = pool_.TypeAt(i); - if (entry_type != ObjectPool::EntryType::kTaggedObject) { - continue; - } - entry_ = pool_.ObjectAt(i); - if (entry_.IsSubtypeTestCache()) { - SubtypeTestCache::Cast(entry_).Reset(); - } - } - } - function.ClearCode(); function.ClearICDataArray(); } private: const bool force_; - Bytecode& bytecode_; ObjectPool& pool_; Object& entry_; }; diff --git a/runtime/vm/class_id.h b/runtime/vm/class_id.h index 0664cbb4d9f..92faca0b651 100644 --- a/runtime/vm/class_id.h +++ b/runtime/vm/class_id.h @@ -31,7 +31,6 @@ typedef uint16_t ClassIdTagType; V(Namespace) \ V(KernelProgramInfo) \ V(Code) \ - V(Bytecode) \ V(Instructions) \ V(InstructionsSection) \ V(ObjectPool) \ @@ -42,7 +41,6 @@ typedef uint16_t ClassIdTagType; V(ExceptionHandlers) \ V(Context) \ V(ContextScope) \ - V(ParameterTypeCheck) \ V(SingleTargetCache) \ V(UnlinkedCall) \ V(MonomorphicSmiableCall) \ diff --git a/runtime/vm/clustered_snapshot.cc b/runtime/vm/clustered_snapshot.cc index e32e798b3ce..8ab009110c9 100644 --- a/runtime/vm/clustered_snapshot.cc +++ b/runtime/vm/clustered_snapshot.cc @@ -250,7 +250,7 @@ class ClassSerializationCluster : public SerializationCluster { s->UnexpectedObject(cls, "Class with non mode agnostic constants"); } if (s->kind() != Snapshot::kFullAOT) { - s->Write(cls->ptr()->binary_declaration_); + s->Write(cls->ptr()->kernel_offset_); } s->Write(Class::target_instance_size_in_words(cls)); s->Write(Class::target_next_field_offset_in_words(cls)); @@ -325,7 +325,7 @@ class ClassDeserializationCluster : public DeserializationCluster { cls->ptr()->id_ = class_id; #if !defined(DART_PRECOMPILED_RUNTIME) if (d->kind() != Snapshot::kFullAOT) { - cls->ptr()->binary_declaration_ = d->Read(); + cls->ptr()->kernel_offset_ = d->Read(); } #endif if (!IsInternalVMdefinedClassId(class_id)) { @@ -372,7 +372,7 @@ class ClassDeserializationCluster : public DeserializationCluster { #if !defined(DART_PRECOMPILED_RUNTIME) if (d->kind() != Snapshot::kFullAOT) { - cls->ptr()->binary_declaration_ = d->Read(); + cls->ptr()->kernel_offset_ = d->Read(); } #endif cls->ptr()->host_instance_size_in_words_ = d->Read(); @@ -598,13 +598,10 @@ class FunctionSerializationCluster : public SerializationCluster { objects_.Add(func); PushFromTo(func); - if ((kind == Snapshot::kFull) || (kind == Snapshot::kFullCore)) { - NOT_IN_PRECOMPILED(s->Push(func->ptr()->bytecode_)); - } else if (kind == Snapshot::kFullAOT) { + if (kind == Snapshot::kFullAOT) { s->Push(func->ptr()->code_); } else if (kind == Snapshot::kFullJIT) { NOT_IN_PRECOMPILED(s->Push(func->ptr()->unoptimized_code_)); - NOT_IN_PRECOMPILED(s->Push(func->ptr()->bytecode_)); s->Push(func->ptr()->code_); s->Push(func->ptr()->ic_data_array_); } @@ -627,13 +624,10 @@ class FunctionSerializationCluster : public SerializationCluster { FunctionPtr func = objects_[i]; AutoTraceObjectName(func, MakeDisambiguatedFunctionName(s, func)); WriteFromTo(func); - if ((kind == Snapshot::kFull) || (kind == Snapshot::kFullCore)) { - NOT_IN_PRECOMPILED(WriteField(func, bytecode_)); - } else if (kind == Snapshot::kFullAOT) { + if (kind == Snapshot::kFullAOT) { WriteField(func, code_); } else if (s->kind() == Snapshot::kFullJIT) { NOT_IN_PRECOMPILED(WriteField(func, unoptimized_code_)); - NOT_IN_PRECOMPILED(WriteField(func, bytecode_)); WriteField(func, code_); WriteField(func, ic_data_array_); } @@ -641,7 +635,7 @@ class FunctionSerializationCluster : public SerializationCluster { if (kind != Snapshot::kFullAOT) { s->WriteTokenPosition(func->ptr()->token_pos_); s->WriteTokenPosition(func->ptr()->end_token_pos_); - s->Write(func->ptr()->binary_declaration_); + s->Write(func->ptr()->kernel_offset_); } s->Write(func->ptr()->packed_fields_); @@ -694,16 +688,11 @@ class FunctionDeserializationCluster : public DeserializationCluster { Function::InstanceSize()); ReadFromTo(func); - if ((kind == Snapshot::kFull) || (kind == Snapshot::kFullCore)) { - NOT_IN_PRECOMPILED(func->ptr()->bytecode_ = - static_cast(d->ReadRef())); - } else if (kind == Snapshot::kFullAOT) { + if (kind == Snapshot::kFullAOT) { func->ptr()->code_ = static_cast(d->ReadRef()); } else if (kind == Snapshot::kFullJIT) { NOT_IN_PRECOMPILED(func->ptr()->unoptimized_code_ = static_cast(d->ReadRef())); - NOT_IN_PRECOMPILED(func->ptr()->bytecode_ = - static_cast(d->ReadRef())); func->ptr()->code_ = static_cast(d->ReadRef()); func->ptr()->ic_data_array_ = static_cast(d->ReadRef()); } @@ -717,7 +706,7 @@ class FunctionDeserializationCluster : public DeserializationCluster { if (kind != Snapshot::kFullAOT) { func->ptr()->token_pos_ = d->ReadTokenPosition(); func->ptr()->end_token_pos_ = d->ReadTokenPosition(); - func->ptr()->binary_declaration_ = d->Read(); + func->ptr()->kernel_offset_ = d->Read(); } func->ptr()->unboxed_parameters_info_.Reset(); #endif @@ -1143,7 +1132,7 @@ class FieldSerializationCluster : public SerializationCluster { s->WriteCid(field->ptr()->guarded_cid_); s->WriteCid(field->ptr()->is_nullable_); s->Write(field->ptr()->static_type_exactness_state_); - s->Write(field->ptr()->binary_declaration_); + s->Write(field->ptr()->kernel_offset_); } s->Write(field->ptr()->kind_bits_); @@ -1213,7 +1202,7 @@ class FieldDeserializationCluster : public DeserializationCluster { field->ptr()->is_nullable_ = d->ReadCid(); field->ptr()->static_type_exactness_state_ = d->Read(); #if !defined(DART_PRECOMPILED_RUNTIME) - field->ptr()->binary_declaration_ = d->Read(); + field->ptr()->kernel_offset_ = d->Read(); #endif } field->ptr()->kind_bits_ = d->Read(); @@ -1359,7 +1348,7 @@ class LibrarySerializationCluster : public SerializationCluster { s->Write(lib->ptr()->load_state_); s->Write(lib->ptr()->flags_); if (s->kind() != Snapshot::kFullAOT) { - s->Write(lib->ptr()->binary_declaration_); + s->Write(lib->ptr()->kernel_offset_); } } } @@ -1398,7 +1387,7 @@ class LibraryDeserializationCluster : public DeserializationCluster { LibraryLayout::InFullSnapshotBit::update(true, d->Read()); #if !defined(DART_PRECOMPILED_RUNTIME) if (d->kind() != Snapshot::kFullAOT) { - lib->ptr()->binary_declaration_ = d->Read(); + lib->ptr()->kernel_offset_ = d->Read(); } #endif } @@ -1982,88 +1971,6 @@ class CodeDeserializationCluster : public DeserializationCluster { }; #if !defined(DART_PRECOMPILED_RUNTIME) -class BytecodeSerializationCluster : public SerializationCluster { - public: - BytecodeSerializationCluster() : SerializationCluster("Bytecode") {} - virtual ~BytecodeSerializationCluster() {} - - void Trace(Serializer* s, ObjectPtr object) { - BytecodePtr bytecode = Bytecode::RawCast(object); - objects_.Add(bytecode); - PushFromTo(bytecode); - } - - void WriteAlloc(Serializer* s) { - s->WriteCid(kBytecodeCid); - const intptr_t count = objects_.length(); - s->WriteUnsigned(count); - for (intptr_t i = 0; i < count; i++) { - BytecodePtr bytecode = objects_[i]; - s->AssignRef(bytecode); - } - } - - void WriteFill(Serializer* s) { - ASSERT(s->kind() != Snapshot::kFullAOT); - const intptr_t count = objects_.length(); - for (intptr_t i = 0; i < count; i++) { - BytecodePtr bytecode = objects_[i]; - s->Write(bytecode->ptr()->instructions_size_); - WriteFromTo(bytecode); - s->Write(bytecode->ptr()->instructions_binary_offset_); - s->Write(bytecode->ptr()->source_positions_binary_offset_); - s->Write(bytecode->ptr()->local_variables_binary_offset_); - } - } - - private: - GrowableArray objects_; -}; - -class BytecodeDeserializationCluster : public DeserializationCluster { - public: - BytecodeDeserializationCluster() : DeserializationCluster("Bytecode") {} - virtual ~BytecodeDeserializationCluster() {} - - void ReadAlloc(Deserializer* d, bool is_canonical) { - start_index_ = d->next_index(); - PageSpace* old_space = d->heap()->old_space(); - const intptr_t count = d->ReadUnsigned(); - for (intptr_t i = 0; i < count; i++) { - d->AssignRef(AllocateUninitialized(old_space, Bytecode::InstanceSize())); - } - stop_index_ = d->next_index(); - } - - void ReadFill(Deserializer* d, bool is_canonical) { - ASSERT(d->kind() != Snapshot::kFullAOT); - - for (intptr_t id = start_index_; id < stop_index_; id++) { - BytecodePtr bytecode = static_cast(d->Ref(id)); - Deserializer::InitializeHeader(bytecode, kBytecodeCid, - Bytecode::InstanceSize()); - bytecode->ptr()->instructions_ = 0; - bytecode->ptr()->instructions_size_ = d->Read(); - ReadFromTo(bytecode); - bytecode->ptr()->instructions_binary_offset_ = d->Read(); - bytecode->ptr()->source_positions_binary_offset_ = d->Read(); - bytecode->ptr()->local_variables_binary_offset_ = d->Read(); - } - } - - void PostLoad(Deserializer* d, const Array& refs, bool is_canonical) { - Bytecode& bytecode = Bytecode::Handle(d->zone()); - ExternalTypedData& binary = ExternalTypedData::Handle(d->zone()); - - for (intptr_t i = start_index_; i < stop_index_; i++) { - bytecode ^= refs.At(i); - binary = bytecode.GetBinary(d->zone()); - bytecode.set_instructions(reinterpret_cast( - binary.DataAddr(bytecode.instructions_binary_offset()))); - } - } -}; - class ObjectPoolSerializationCluster : public SerializationCluster { public: ObjectPoolSerializationCluster() : SerializationCluster("ObjectPool") {} @@ -2077,8 +1984,7 @@ class ObjectPoolSerializationCluster : public SerializationCluster { uint8_t* entry_bits = pool->ptr()->entry_bits(); for (intptr_t i = 0; i < length; i++) { auto entry_type = ObjectPool::TypeBits::decode(entry_bits[i]); - if ((entry_type == ObjectPool::EntryType::kTaggedObject) || - (entry_type == ObjectPool::EntryType::kNativeEntryData)) { + if (entry_type == ObjectPool::EntryType::kTaggedObject) { s->Push(pool->ptr()->data()[i].raw_obj_); } } @@ -2125,22 +2031,6 @@ class ObjectPoolSerializationCluster : public SerializationCluster { s->Write(entry.raw_value_); break; } - case ObjectPool::EntryType::kNativeEntryData: { - ObjectPtr raw = entry.raw_obj_; - TypedDataPtr raw_data = static_cast(raw); - // kNativeEntryData object pool entries are for linking natives for - // the interpreter. Before writing these entries into the snapshot, - // we need to unlink them by nulling out the 'trampoline' and - // 'native_function' fields. - NativeEntryData::Payload* payload = - NativeEntryData::FromTypedArray(raw_data); - if (payload->kind == MethodRecognizer::kUnknown) { - payload->trampoline = NULL; - payload->native_function = NULL; - } - s->WriteElementRef(raw, j); - break; - } case ObjectPool::EntryType::kNativeFunction: case ObjectPool::EntryType::kNativeFunctionWrapper: { // Write nothing. Will initialize with the lazy link entry. @@ -2187,7 +2077,6 @@ class ObjectPoolDeserializationCluster : public DeserializationCluster { pool->ptr()->entry_bits()[j] = entry_bits; ObjectPoolLayout::Entry& entry = pool->ptr()->data()[j]; switch (ObjectPool::TypeBits::decode(entry_bits)) { - case ObjectPool::EntryType::kNativeEntryData: case ObjectPool::EntryType::kTaggedObject: entry.raw_obj_ = d->ReadRef(); break; @@ -2755,72 +2644,6 @@ class ContextScopeDeserializationCluster : public DeserializationCluster { } }; -#if !defined(DART_PRECOMPILED_RUNTIME) -class ParameterTypeCheckSerializationCluster : public SerializationCluster { - public: - ParameterTypeCheckSerializationCluster() - : SerializationCluster("ParameterTypeCheck") {} - ~ParameterTypeCheckSerializationCluster() {} - - void Trace(Serializer* s, ObjectPtr object) { - ParameterTypeCheckPtr unlinked = ParameterTypeCheck::RawCast(object); - objects_.Add(unlinked); - PushFromTo(unlinked); - } - - void WriteAlloc(Serializer* s) { - s->WriteCid(kParameterTypeCheckCid); - const intptr_t count = objects_.length(); - s->WriteUnsigned(count); - for (intptr_t i = 0; i < count; i++) { - ParameterTypeCheckPtr check = objects_[i]; - s->AssignRef(check); - } - } - - void WriteFill(Serializer* s) { - const intptr_t count = objects_.length(); - for (intptr_t i = 0; i < count; i++) { - ParameterTypeCheckPtr check = objects_[i]; - s->Write(check->ptr()->index_); - WriteFromTo(check); - } - } - - private: - GrowableArray objects_; -}; -#endif // !DART_PRECOMPILED_RUNTIME - -class ParameterTypeCheckDeserializationCluster : public DeserializationCluster { - public: - ParameterTypeCheckDeserializationCluster() - : DeserializationCluster("ParameterTypeCheck") {} - ~ParameterTypeCheckDeserializationCluster() {} - - void ReadAlloc(Deserializer* d, bool is_canonical) { - start_index_ = d->next_index(); - PageSpace* old_space = d->heap()->old_space(); - const intptr_t count = d->ReadUnsigned(); - for (intptr_t i = 0; i < count; i++) { - d->AssignRef( - AllocateUninitialized(old_space, ParameterTypeCheck::InstanceSize())); - } - stop_index_ = d->next_index(); - } - - void ReadFill(Deserializer* d, bool is_canonical) { - for (intptr_t id = start_index_; id < stop_index_; id++) { - ParameterTypeCheckPtr check = - static_cast(d->Ref(id)); - Deserializer::InitializeHeader(check, kParameterTypeCheckCid, - ParameterTypeCheck::InstanceSize()); - check->ptr()->index_ = d->Read(); - ReadFromTo(check); - } - } -}; - #if !defined(DART_PRECOMPILED_RUNTIME) class UnlinkedCallSerializationCluster : public SerializationCluster { public: @@ -5024,22 +4847,6 @@ class VMSerializationRoots : public SerializationRoots { "LocalVarDescriptors", ""); s->AddBaseObject(Object::empty_exception_handlers().raw(), "ExceptionHandlers", ""); - s->AddBaseObject(Object::implicit_getter_bytecode().raw(), "Bytecode", - ""); - s->AddBaseObject(Object::implicit_setter_bytecode().raw(), "Bytecode", - ""); - s->AddBaseObject(Object::implicit_static_getter_bytecode().raw(), - "Bytecode", ""); - s->AddBaseObject(Object::method_extractor_bytecode().raw(), "Bytecode", - ""); - s->AddBaseObject(Object::invoke_closure_bytecode().raw(), "Bytecode", - ""); - s->AddBaseObject(Object::invoke_field_bytecode().raw(), "Bytecode", - ""); - s->AddBaseObject(Object::nsm_dispatcher_bytecode().raw(), "Bytecode", - ""); - s->AddBaseObject(Object::dynamic_invocation_forwarder_bytecode().raw(), - "Bytecode", ""); for (intptr_t i = 0; i < ArgumentsDescriptor::kCachedDescriptorCount; i++) { s->AddBaseObject(ArgumentsDescriptor::cached_args_descriptors_[i], @@ -5121,14 +4928,6 @@ class VMDeserializationRoots : public DeserializationRoots { d->AddBaseObject(Object::empty_descriptors().raw()); d->AddBaseObject(Object::empty_var_descriptors().raw()); d->AddBaseObject(Object::empty_exception_handlers().raw()); - d->AddBaseObject(Object::implicit_getter_bytecode().raw()); - d->AddBaseObject(Object::implicit_setter_bytecode().raw()); - d->AddBaseObject(Object::implicit_static_getter_bytecode().raw()); - d->AddBaseObject(Object::method_extractor_bytecode().raw()); - d->AddBaseObject(Object::invoke_closure_bytecode().raw()); - d->AddBaseObject(Object::invoke_field_bytecode().raw()); - d->AddBaseObject(Object::nsm_dispatcher_bytecode().raw()); - d->AddBaseObject(Object::dynamic_invocation_forwarder_bytecode().raw()); for (intptr_t i = 0; i < ArgumentsDescriptor::kCachedDescriptorCount; i++) { d->AddBaseObject(ArgumentsDescriptor::cached_args_descriptors_[i]); @@ -5754,8 +5553,6 @@ SerializationCluster* Serializer::NewClusterForClass(intptr_t cid) { return new (Z) KernelProgramInfoSerializationCluster(); case kCodeCid: return new (Z) CodeSerializationCluster(heap_); - case kBytecodeCid: - return new (Z) BytecodeSerializationCluster(); case kObjectPoolCid: return new (Z) ObjectPoolSerializationCluster(); case kPcDescriptorsCid: @@ -5766,8 +5563,6 @@ SerializationCluster* Serializer::NewClusterForClass(intptr_t cid) { return new (Z) ContextSerializationCluster(); case kContextScopeCid: return new (Z) ContextScopeSerializationCluster(); - case kParameterTypeCheckCid: - return new (Z) ParameterTypeCheckSerializationCluster(); case kUnlinkedCallCid: return new (Z) UnlinkedCallSerializationCluster(); case kICDataCid: @@ -5934,12 +5729,6 @@ void Serializer::Push(ObjectPtr object) { !Snapshot::IncludesCode(kind_)) { return; // Do not trace, will write null. } -#if !defined(DART_PRECOMPILED_RUNTIME) - if (object->IsHeapObject() && object->IsBytecode() && - !Snapshot::IncludesBytecode(kind_)) { - return; // Do not trace, will write null. - } -#endif // !DART_PRECOMPILED_RUNTIME intptr_t id = heap_->GetObjectId(object); if (id == kUnreachableReference) { @@ -6458,10 +6247,6 @@ DeserializationCluster* Deserializer::ReadCluster() { #endif // !DART_PRECOMPILED_RUNTIME case kCodeCid: return new (Z) CodeDeserializationCluster(); -#if !defined(DART_PRECOMPILED_RUNTIME) - case kBytecodeCid: - return new (Z) BytecodeDeserializationCluster(); -#endif // !DART_PRECOMPILED_RUNTIME case kObjectPoolCid: return new (Z) ObjectPoolDeserializationCluster(); case kPcDescriptorsCid: @@ -6472,8 +6257,6 @@ DeserializationCluster* Deserializer::ReadCluster() { return new (Z) ContextDeserializationCluster(); case kContextScopeCid: return new (Z) ContextScopeDeserializationCluster(); - case kParameterTypeCheckCid: - return new (Z) ParameterTypeCheckDeserializationCluster(); case kUnlinkedCallCid: return new (Z) UnlinkedCallDeserializationCluster(); case kICDataCid: diff --git a/runtime/vm/clustered_snapshot.h b/runtime/vm/clustered_snapshot.h index c02f85f4b17..dbfa8d847ab 100644 --- a/runtime/vm/clustered_snapshot.h +++ b/runtime/vm/clustered_snapshot.h @@ -413,11 +413,6 @@ class Serializer : public ThreadStackResource { if (object->IsCode() && !Snapshot::IncludesCode(kind_)) { return RefId(Object::null()); } -#if !defined(DART_PRECOMPILED_RUNTIME) - if (object->IsBytecode() && !Snapshot::IncludesBytecode(kind_)) { - return RefId(Object::null()); - } -#endif // !DART_PRECOMPILED_RUNTIME FATAL("Missing ref"); } diff --git a/runtime/vm/code_patcher.h b/runtime/vm/code_patcher.h index ba7ff046417..30828a1c137 100644 --- a/runtime/vm/code_patcher.h +++ b/runtime/vm/code_patcher.h @@ -107,18 +107,6 @@ class CodePatcher : public AllStatic { // Example pattern: `[0x3d, 0x8b, -1, -1]`. bool MatchesPattern(uword end, const int16_t* pattern, intptr_t size); -class KBCPatcher : public AllStatic { - public: - static NativeFunctionWrapper GetNativeCallAt(uword return_address, - const Bytecode& bytecode, - NativeFunction* function); - - static void PatchNativeCallAt(uword return_address, - const Bytecode& bytecode, - NativeFunction function, - NativeFunctionWrapper trampoline); -}; - } // namespace dart #endif // RUNTIME_VM_CODE_PATCHER_H_ diff --git a/runtime/vm/code_patcher_kbc.cc b/runtime/vm/code_patcher_kbc.cc deleted file mode 100644 index 2dd74bda9f7..00000000000 --- a/runtime/vm/code_patcher_kbc.cc +++ /dev/null @@ -1,38 +0,0 @@ -// Copyright (c) 2018, the Dart project authors. Please see the AUTHORS file -// for details. All rights reserved. Use of this source code is governed by a -// BSD-style license that can be found in the LICENSE file. - -#include "vm/globals.h" -#if !defined(DART_PRECOMPILED_RUNTIME) - -#include "vm/code_patcher.h" - -#include "vm/instructions_kbc.h" -#include "vm/native_entry.h" - -namespace dart { - -void KBCPatcher::PatchNativeCallAt(uword return_address, - const Bytecode& bytecode, - NativeFunction function, - NativeFunctionWrapper trampoline) { - ASSERT(bytecode.ContainsInstructionAt(return_address)); - NativeEntryData native_entry_data(TypedData::Handle( - KBCNativeCallPattern::GetNativeEntryDataAt(return_address, bytecode))); - native_entry_data.set_trampoline(trampoline); - native_entry_data.set_native_function(function); -} - -NativeFunctionWrapper KBCPatcher::GetNativeCallAt(uword return_address, - const Bytecode& bytecode, - NativeFunction* function) { - ASSERT(bytecode.ContainsInstructionAt(return_address)); - NativeEntryData native_entry_data(TypedData::Handle( - KBCNativeCallPattern::GetNativeEntryDataAt(return_address, bytecode))); - *function = native_entry_data.native_function(); - return native_entry_data.trampoline(); -} - -} // namespace dart - -#endif // !defined(DART_PRECOMPILED_RUNTIME) diff --git a/runtime/vm/compiler/aot/precompiler.cc b/runtime/vm/compiler/aot/precompiler.cc index f65262662cf..0b503e5ab72 100644 --- a/runtime/vm/compiler/aot/precompiler.cc +++ b/runtime/vm/compiler/aot/precompiler.cc @@ -278,7 +278,7 @@ void Precompiler::DoCompileAll() { if (FLAG_use_bare_instructions) { // We use any stub here to get it's object pool (all stubs share the // same object pool in bare instructions mode). - const Code& code = StubCode::InterpretCall(); + const Code& code = StubCode::LazyCompile(); const ObjectPool& stub_pool = ObjectPool::Handle(code.object_pool()); global_object_pool_builder()->Reset(); @@ -420,7 +420,6 @@ void Precompiler::DoCompileAll() { I->object_store()->set_async_star_move_next_helper(null_function); I->object_store()->set_complete_on_async_return(null_function); I->object_store()->set_async_star_stream_controller(null_class); - I->object_store()->set_bytecode_attributes(Array::null_array()); DropMetadata(); DropLibraryEntries(); } @@ -1745,7 +1744,6 @@ void Precompiler::DropFunctions() { for (intptr_t j = 0; j < functions.Length(); j++) { function ^= functions.At(j); function.DropUncompiledImplicitClosureFunction(); - function.ClearBytecode(); if (functions_to_retain_.ContainsKey(function)) { retained_functions.Add(function); } else { @@ -1795,7 +1793,6 @@ void Precompiler::DropFunctions() { retained_functions = GrowableObjectArray::New(); for (intptr_t j = 0; j < closures.Length(); j++) { function ^= closures.At(j); - function.ClearBytecode(); if (functions_to_retain_.ContainsKey(function)) { retained_functions.Add(function); } else { @@ -1812,7 +1809,6 @@ void Precompiler::DropFields() { Field& field = Field::Handle(Z); GrowableObjectArray& retained_fields = GrowableObjectArray::Handle(Z); AbstractType& type = AbstractType::Handle(Z); - Function& initializer_function = Function::Handle(Z); SafepointWriteRwLocker ml(T, T->isolate_group()->program_lock()); for (intptr_t i = 0; i < libraries_.Length(); i++) { @@ -1825,10 +1821,6 @@ void Precompiler::DropFields() { for (intptr_t j = 0; j < fields.Length(); j++) { field ^= fields.At(j); bool retain = fields_to_retain_.HasKey(&field); - if (field.HasInitializerFunction()) { - initializer_function = field.InitializerFunction(); - initializer_function.ClearBytecode(); - } #if !defined(PRODUCT) if (field.is_instance() && cls.is_allocated()) { // Keep instance fields so their names are available to graph tools. @@ -2228,7 +2220,6 @@ void Precompiler::DropLibraryEntries() { program_info.set_scripts(Array::null_array()); program_info.set_libraries_cache(Array::null_array()); program_info.set_classes_cache(Array::null_array()); - program_info.set_bytecode_component(Array::null_array()); } script.set_resolved_url(String::null_string()); script.set_compile_time_constants(Array::null_array()); diff --git a/runtime/vm/compiler/aot/precompiler.h b/runtime/vm/compiler/aot/precompiler.h index e80a81c11a5..41a7902aa4e 100644 --- a/runtime/vm/compiler/aot/precompiler.h +++ b/runtime/vm/compiler/aot/precompiler.h @@ -96,7 +96,7 @@ class FieldKeyValueTrait { if (token_pos.IsReal()) { return token_pos.value(); } - return key->binary_declaration_offset(); + return key->kernel_offset(); } static inline bool IsKeyEqual(Pair pair, Key key) { diff --git a/runtime/vm/compiler/assembler/assembler_arm.cc b/runtime/vm/compiler/assembler/assembler_arm.cc index 4b84af624c4..8417f7ccb84 100644 --- a/runtime/vm/compiler/assembler/assembler_arm.cc +++ b/runtime/vm/compiler/assembler/assembler_arm.cc @@ -639,7 +639,7 @@ void Assembler::TransitionNativeToGenerated(Register addr, } // Mark that the thread is executing Dart code. - LoadImmediate(state, target::Thread::vm_tag_compiled_id()); + LoadImmediate(state, target::Thread::vm_tag_dart_id()); StoreToOffset(kWord, state, THR, target::Thread::vm_tag_offset()); LoadImmediate(state, target::Thread::generated_execution_state()); StoreToOffset(kWord, state, THR, target::Thread::execution_state_offset()); diff --git a/runtime/vm/compiler/assembler/assembler_arm64.cc b/runtime/vm/compiler/assembler/assembler_arm64.cc index f8089ac45a8..67d07c8f6e5 100644 --- a/runtime/vm/compiler/assembler/assembler_arm64.cc +++ b/runtime/vm/compiler/assembler/assembler_arm64.cc @@ -1483,7 +1483,7 @@ void Assembler::TransitionNativeToGenerated(Register state, } // Mark that the thread is executing Dart code. - LoadImmediate(state, target::Thread::vm_tag_compiled_id()); + LoadImmediate(state, target::Thread::vm_tag_dart_id()); StoreToOffset(state, THR, target::Thread::vm_tag_offset()); LoadImmediate(state, target::Thread::generated_execution_state()); StoreToOffset(state, THR, target::Thread::execution_state_offset()); diff --git a/runtime/vm/compiler/assembler/assembler_ia32.cc b/runtime/vm/compiler/assembler/assembler_ia32.cc index 07af2efdea6..06f27c25652 100644 --- a/runtime/vm/compiler/assembler/assembler_ia32.cc +++ b/runtime/vm/compiler/assembler/assembler_ia32.cc @@ -2288,8 +2288,7 @@ void Assembler::TransitionNativeToGenerated(Register scratch, } // Mark that the thread is executing Dart code. - movl(Assembler::VMTagAddress(), - Immediate(target::Thread::vm_tag_compiled_id())); + movl(Assembler::VMTagAddress(), Immediate(target::Thread::vm_tag_dart_id())); movl(Address(THR, target::Thread::execution_state_offset()), Immediate(target::Thread::generated_execution_state())); diff --git a/runtime/vm/compiler/assembler/assembler_x64.cc b/runtime/vm/compiler/assembler/assembler_x64.cc index 0a833cfa47e..779eadd6b5c 100644 --- a/runtime/vm/compiler/assembler/assembler_x64.cc +++ b/runtime/vm/compiler/assembler/assembler_x64.cc @@ -245,8 +245,7 @@ void Assembler::TransitionNativeToGenerated(bool leave_safepoint) { #endif } - movq(Assembler::VMTagAddress(), - Immediate(target::Thread::vm_tag_compiled_id())); + movq(Assembler::VMTagAddress(), Immediate(target::Thread::vm_tag_dart_id())); movq(Address(THR, target::Thread::execution_state_offset()), Immediate(target::Thread::generated_execution_state())); diff --git a/runtime/vm/compiler/assembler/disassembler_kbc.cc b/runtime/vm/compiler/assembler/disassembler_kbc.cc deleted file mode 100644 index 2f0d0d0e4f9..00000000000 --- a/runtime/vm/compiler/assembler/disassembler_kbc.cc +++ /dev/null @@ -1,456 +0,0 @@ -// Copyright (c) 2018, the Dart project authors. Please see the AUTHORS file -// for details. All rights reserved. Use of this source code is governed by a -// BSD-style license that can be found in the LICENSE file. - -#include "vm/globals.h" -#if !defined(DART_PRECOMPILED_RUNTIME) - -#include "vm/compiler/assembler/disassembler_kbc.h" - -#include "platform/assert.h" -#include "vm/compiler/frontend/bytecode_reader.h" -#include "vm/constants_kbc.h" -#include "vm/cpu.h" -#include "vm/instructions.h" - -namespace dart { - -static const char* kOpcodeNames[] = { -#define BYTECODE_NAME(name, encoding, kind, op1, op2, op3) #name, - KERNEL_BYTECODES_LIST(BYTECODE_NAME) -#undef BYTECODE_NAME -}; - -static const size_t kOpcodeCount = - sizeof(kOpcodeNames) / sizeof(kOpcodeNames[0]); -static_assert(kOpcodeCount <= 256, "Opcode should fit into a byte"); - -typedef void (*BytecodeFormatter)(char* buffer, - intptr_t size, - KernelBytecode::Opcode opcode, - const KBCInstr* instr); -typedef void (*Fmt)(char** buf, - intptr_t* size, - const KBCInstr* instr, - int32_t value); - -template -void FormatOperand(char** buf, - intptr_t* size, - const char* fmt, - ValueType value) { - intptr_t written = Utils::SNPrint(*buf, *size, fmt, value); - if (written < *size) { - *buf += written; - *size += written; - } else { - *size = -1; - } -} - -static void Fmt___(char** buf, - intptr_t* size, - const KBCInstr* instr, - int32_t value) {} - -static void Fmttgt(char** buf, - intptr_t* size, - const KBCInstr* instr, - int32_t value) { - if (FLAG_disassemble_relative) { - FormatOperand(buf, size, "-> %" Pd, value); - } else { - FormatOperand(buf, size, "-> %" Px, instr + value); - } -} - -static void Fmtlit(char** buf, - intptr_t* size, - const KBCInstr* instr, - int32_t value) { - FormatOperand(buf, size, "k%d", value); -} - -static void Fmtreg(char** buf, - intptr_t* size, - const KBCInstr* instr, - int32_t value) { - FormatOperand(buf, size, "r%d", value); -} - -static void Fmtxeg(char** buf, - intptr_t* size, - const KBCInstr* instr, - int32_t value) { - if (value < 0) { - FormatOperand(buf, size, "FP[%d]", value); - } else { - Fmtreg(buf, size, instr, value); - } -} - -static void Fmtnum(char** buf, - intptr_t* size, - const KBCInstr* instr, - int32_t value) { - FormatOperand(buf, size, "#%d", value); -} - -static void Apply(char** buf, - intptr_t* size, - const KBCInstr* instr, - Fmt fmt, - int32_t value, - const char* suffix) { - if (*size <= 0) { - return; - } - - fmt(buf, size, instr, value); - if (*size > 0) { - FormatOperand(buf, size, "%s", suffix); - } -} - -static void Format0(char* buf, - intptr_t size, - KernelBytecode::Opcode opcode, - const KBCInstr* instr, - Fmt op1, - Fmt op2, - Fmt op3) {} - -static void FormatA(char* buf, - intptr_t size, - KernelBytecode::Opcode opcode, - const KBCInstr* instr, - Fmt op1, - Fmt op2, - Fmt op3) { - const int32_t a = KernelBytecode::DecodeA(instr); - Apply(&buf, &size, instr, op1, a, ""); -} - -static void FormatD(char* buf, - intptr_t size, - KernelBytecode::Opcode opcode, - const KBCInstr* instr, - Fmt op1, - Fmt op2, - Fmt op3) { - const int32_t bc = KernelBytecode::DecodeD(instr); - Apply(&buf, &size, instr, op1, bc, ""); -} - -static void FormatX(char* buf, - intptr_t size, - KernelBytecode::Opcode opcode, - const KBCInstr* instr, - Fmt op1, - Fmt op2, - Fmt op3) { - const int32_t bc = KernelBytecode::DecodeX(instr); - Apply(&buf, &size, instr, op1, bc, ""); -} - -static void FormatT(char* buf, - intptr_t size, - KernelBytecode::Opcode opcode, - const KBCInstr* instr, - Fmt op1, - Fmt op2, - Fmt op3) { - const int32_t x = KernelBytecode::DecodeT(instr); - Apply(&buf, &size, instr, op1, x, ""); -} - -static void FormatA_E(char* buf, - intptr_t size, - KernelBytecode::Opcode opcode, - const KBCInstr* instr, - Fmt op1, - Fmt op2, - Fmt op3) { - const int32_t a = KernelBytecode::DecodeA(instr); - const int32_t e = KernelBytecode::DecodeE(instr); - Apply(&buf, &size, instr, op1, a, ", "); - Apply(&buf, &size, instr, op2, e, ""); -} - -static void FormatA_Y(char* buf, - intptr_t size, - KernelBytecode::Opcode opcode, - const KBCInstr* instr, - Fmt op1, - Fmt op2, - Fmt op3) { - const int32_t a = KernelBytecode::DecodeA(instr); - const int32_t y = KernelBytecode::DecodeY(instr); - Apply(&buf, &size, instr, op1, a, ", "); - Apply(&buf, &size, instr, op2, y, ""); -} - -static void FormatD_F(char* buf, - intptr_t size, - KernelBytecode::Opcode opcode, - const KBCInstr* instr, - Fmt op1, - Fmt op2, - Fmt op3) { - const int32_t d = KernelBytecode::DecodeD(instr); - const int32_t f = KernelBytecode::DecodeF(instr); - Apply(&buf, &size, instr, op1, d, ", "); - Apply(&buf, &size, instr, op2, f, ""); -} - -static void FormatA_B_C(char* buf, - intptr_t size, - KernelBytecode::Opcode opcode, - const KBCInstr* instr, - Fmt op1, - Fmt op2, - Fmt op3) { - const int32_t a = KernelBytecode::DecodeA(instr); - const int32_t b = KernelBytecode::DecodeB(instr); - const int32_t c = KernelBytecode::DecodeC(instr); - Apply(&buf, &size, instr, op1, a, ", "); - Apply(&buf, &size, instr, op2, b, ", "); - Apply(&buf, &size, instr, op3, c, ""); -} - -#define BYTECODE_FORMATTER(name, encoding, kind, op1, op2, op3) \ - static void Format##name(char* buf, intptr_t size, \ - KernelBytecode::Opcode opcode, \ - const KBCInstr* instr) { \ - Format##encoding(buf, size, opcode, instr, Fmt##op1, Fmt##op2, Fmt##op3); \ - } -KERNEL_BYTECODES_LIST(BYTECODE_FORMATTER) -#undef BYTECODE_FORMATTER - -static const BytecodeFormatter kFormatters[] = { -#define BYTECODE_FORMATTER(name, encoding, kind, op1, op2, op3) &Format##name, - KERNEL_BYTECODES_LIST(BYTECODE_FORMATTER) -#undef BYTECODE_FORMATTER -}; - -static intptr_t GetConstantPoolIndex(const KBCInstr* instr) { - switch (KernelBytecode::DecodeOpcode(instr)) { - case KernelBytecode::kLoadConstant: - case KernelBytecode::kLoadConstant_Wide: - case KernelBytecode::kInstantiateTypeArgumentsTOS: - case KernelBytecode::kInstantiateTypeArgumentsTOS_Wide: - case KernelBytecode::kAssertAssignable: - case KernelBytecode::kAssertAssignable_Wide: - return KernelBytecode::DecodeE(instr); - - case KernelBytecode::kPushConstant: - case KernelBytecode::kPushConstant_Wide: - case KernelBytecode::kInitLateField: - case KernelBytecode::kInitLateField_Wide: - case KernelBytecode::kStoreStaticTOS: - case KernelBytecode::kStoreStaticTOS_Wide: - case KernelBytecode::kLoadStatic: - case KernelBytecode::kLoadStatic_Wide: - case KernelBytecode::kAllocate: - case KernelBytecode::kAllocate_Wide: - case KernelBytecode::kAllocateClosure: - case KernelBytecode::kAllocateClosure_Wide: - case KernelBytecode::kInstantiateType: - case KernelBytecode::kInstantiateType_Wide: - case KernelBytecode::kDirectCall: - case KernelBytecode::kDirectCall_Wide: - case KernelBytecode::kUncheckedDirectCall: - case KernelBytecode::kUncheckedDirectCall_Wide: - case KernelBytecode::kInterfaceCall: - case KernelBytecode::kInterfaceCall_Wide: - case KernelBytecode::kInstantiatedInterfaceCall: - case KernelBytecode::kInstantiatedInterfaceCall_Wide: - case KernelBytecode::kUncheckedClosureCall: - case KernelBytecode::kUncheckedClosureCall_Wide: - case KernelBytecode::kUncheckedInterfaceCall: - case KernelBytecode::kUncheckedInterfaceCall_Wide: - case KernelBytecode::kDynamicCall: - case KernelBytecode::kDynamicCall_Wide: - return KernelBytecode::DecodeD(instr); - - default: - return -1; - } -} - -static bool GetLoadedObjectAt(uword pc, - const ObjectPool& object_pool, - Object* obj) { - const KBCInstr* instr = reinterpret_cast(pc); - const intptr_t index = GetConstantPoolIndex(instr); - if (index >= 0) { - if (object_pool.TypeAt(index) == ObjectPool::EntryType::kTaggedObject) { - *obj = object_pool.ObjectAt(index); - return true; - } - } - return false; -} - -void KernelBytecodeDisassembler::DecodeInstruction(char* hex_buffer, - intptr_t hex_size, - char* human_buffer, - intptr_t human_size, - int* out_instr_size, - const Bytecode& bytecode, - Object** object, - uword pc) { - const KBCInstr* instr = reinterpret_cast(pc); - const KernelBytecode::Opcode opcode = KernelBytecode::DecodeOpcode(instr); - const intptr_t instr_size = KernelBytecode::kInstructionSize[opcode]; - - size_t name_size = - Utils::SNPrint(human_buffer, human_size, "%-10s\t", kOpcodeNames[opcode]); - human_buffer += name_size; - human_size -= name_size; - kFormatters[opcode](human_buffer, human_size, opcode, instr); - - const intptr_t kCharactersPerByte = 3; - if (hex_size > instr_size * kCharactersPerByte) { - for (intptr_t i = 0; i < instr_size; ++i) { - Utils::SNPrint(hex_buffer + (i * kCharactersPerByte), - hex_size - (i * kCharactersPerByte), " %02x", instr[i]); - } - } - if (out_instr_size != nullptr) { - *out_instr_size = instr_size; - } - - *object = NULL; - if (!bytecode.IsNull()) { - *object = &Object::Handle(); - const ObjectPool& pool = ObjectPool::Handle(bytecode.object_pool()); - if (!GetLoadedObjectAt(pc, pool, *object)) { - *object = NULL; - } - } -} - -void KernelBytecodeDisassembler::Disassemble(uword start, - uword end, - DisassemblyFormatter* formatter, - const Bytecode& bytecode) { -#if !defined(PRODUCT) - ASSERT(formatter != NULL); - char hex_buffer[kHexadecimalBufferSize]; // Instruction in hexadecimal form. - char human_buffer[kUserReadableBufferSize]; // Human-readable instruction. - uword pc = start; - GrowableArray inlined_functions; - GrowableArray token_positions; - while (pc < end) { - int instruction_length; - Object* object; - DecodeInstruction(hex_buffer, sizeof(hex_buffer), human_buffer, - sizeof(human_buffer), &instruction_length, bytecode, - &object, pc); - formatter->ConsumeInstruction(hex_buffer, sizeof(hex_buffer), human_buffer, - sizeof(human_buffer), object, - FLAG_disassemble_relative ? pc - start : pc); - pc += instruction_length; - } -#else - UNREACHABLE(); -#endif -} - -void KernelBytecodeDisassembler::Disassemble(const Function& function) { -#if !defined(PRODUCT) - ASSERT(function.HasBytecode()); - const char* function_fullname = function.ToFullyQualifiedCString(); - Zone* zone = Thread::Current()->zone(); - const Bytecode& bytecode = Bytecode::Handle(zone, function.bytecode()); - THR_Print("Bytecode for function '%s' {\n", function_fullname); - const uword start = bytecode.PayloadStart(); - const uword base = FLAG_disassemble_relative ? 0 : start; - DisassembleToStdout stdout_formatter; - LogBlock lb; - Disassemble(start, start + bytecode.Size(), &stdout_formatter, bytecode); - THR_Print("}\n"); - - const ObjectPool& object_pool = - ObjectPool::Handle(zone, bytecode.object_pool()); - object_pool.DebugPrint(); - - THR_Print("PC Descriptors for function '%s' {\n", function_fullname); - PcDescriptors::PrintHeaderString(); - const PcDescriptors& descriptors = - PcDescriptors::Handle(zone, bytecode.pc_descriptors()); - THR_Print("%s}\n", descriptors.ToCString()); - - if (bytecode.HasSourcePositions()) { - THR_Print("Source positions for function '%s' {\n", function_fullname); - // 4 bits per hex digit + 2 for "0x". - const int addr_width = (kBitsPerWord / 4) + 2; - // "*" in a printf format specifier tells it to read the field width from - // the printf argument list. - THR_Print("%-*s\tpos\tline\tcolumn\tyield\n", addr_width, "pc"); - const Script& script = Script::Handle(zone, function.script()); - kernel::BytecodeSourcePositionsIterator iter(zone, bytecode); - while (iter.MoveNext()) { - TokenPosition pos = iter.TokenPos(); - intptr_t line = -1, column = -1; - script.GetTokenLocation(pos, &line, &column); - THR_Print("%#-*" Px "\t%s\t%" Pd "\t%" Pd "\t%s\n", addr_width, - base + iter.PcOffset(), pos.ToCString(), line, column, - iter.IsYieldPoint() ? "yield" : ""); - } - THR_Print("}\n"); - } - - if (FLAG_print_variable_descriptors && bytecode.HasLocalVariablesInfo()) { - THR_Print("Local variables info for function '%s' {\n", function_fullname); - kernel::BytecodeLocalVariablesIterator iter(zone, bytecode); - while (iter.MoveNext()) { - switch (iter.Kind()) { - case kernel::BytecodeLocalVariablesIterator::kScope: { - THR_Print("scope 0x%" Px "-0x%" Px " pos %s-%s\tlev %" Pd "\n", - base + iter.StartPC(), base + iter.EndPC(), - iter.StartTokenPos().ToCString(), - iter.EndTokenPos().ToCString(), iter.ContextLevel()); - } break; - case kernel::BytecodeLocalVariablesIterator::kVariableDeclaration: { - THR_Print("var 0x%" Px "-0x%" Px " pos %s-%s\tidx %" Pd - "\tdecl %s\t%s %s %s\n", - base + iter.StartPC(), base + iter.EndPC(), - iter.StartTokenPos().ToCString(), - iter.EndTokenPos().ToCString(), iter.Index(), - iter.DeclarationTokenPos().ToCString(), - String::Handle( - zone, AbstractType::Handle(zone, iter.Type()).Name()) - .ToCString(), - String::Handle(zone, iter.Name()).ToCString(), - iter.IsCaptured() ? "captured" : ""); - } break; - case kernel::BytecodeLocalVariablesIterator::kContextVariable: { - THR_Print("ctxt 0x%" Px "\tidx %" Pd "\n", base + iter.StartPC(), - iter.Index()); - } break; - } - } - THR_Print("}\n"); - - THR_Print("Local variable descriptors for function '%s' {\n", - function_fullname); - const auto& var_descriptors = - LocalVarDescriptors::Handle(zone, bytecode.GetLocalVarDescriptors()); - THR_Print("%s}\n", var_descriptors.ToCString()); - } - - THR_Print("Exception Handlers for function '%s' {\n", function_fullname); - const ExceptionHandlers& handlers = - ExceptionHandlers::Handle(zone, bytecode.exception_handlers()); - THR_Print("%s}\n", handlers.ToCString()); - -#else - UNREACHABLE(); -#endif -} - -} // namespace dart - -#endif // !defined(DART_PRECOMPILED_RUNTIME) diff --git a/runtime/vm/compiler/assembler/disassembler_kbc.h b/runtime/vm/compiler/assembler/disassembler_kbc.h deleted file mode 100644 index 89bbc183f2f..00000000000 --- a/runtime/vm/compiler/assembler/disassembler_kbc.h +++ /dev/null @@ -1,89 +0,0 @@ -// Copyright (c) 2018, the Dart project authors. Please see the AUTHORS file -// for details. All rights reserved. Use of this source code is governed by a -// BSD-style license that can be found in the LICENSE file. - -#ifndef RUNTIME_VM_COMPILER_ASSEMBLER_DISASSEMBLER_KBC_H_ -#define RUNTIME_VM_COMPILER_ASSEMBLER_DISASSEMBLER_KBC_H_ - -#include "vm/globals.h" -#if !defined(DART_PRECOMPILED_RUNTIME) - -#include "vm/compiler/assembler/disassembler.h" - -namespace dart { - -// Disassemble instructions. -class KernelBytecodeDisassembler : public AllStatic { - public: - // Disassemble instructions between start and end. - // (The assumption is that start is at a valid instruction). - // Return true if all instructions were successfully decoded, false otherwise. - static void Disassemble(uword start, - uword end, - DisassemblyFormatter* formatter, - const Bytecode& bytecode); - - static void Disassemble(uword start, - uword end, - DisassemblyFormatter* formatter) { - Disassemble(start, end, formatter, Bytecode::Handle()); - } - - static void Disassemble(uword start, uword end, const Bytecode& bytecode) { -#if !defined(PRODUCT) - DisassembleToStdout stdout_formatter; - LogBlock lb; - Disassemble(start, end, &stdout_formatter, bytecode); -#else - UNREACHABLE(); -#endif - } - - static void Disassemble(uword start, uword end) { -#if !defined(PRODUCT) - DisassembleToStdout stdout_formatter; - LogBlock lb; - Disassemble(start, end, &stdout_formatter); -#else - UNREACHABLE(); -#endif - } - - static void Disassemble(uword start, - uword end, - char* buffer, - uintptr_t buffer_size) { -#if !defined(PRODUCT) - DisassembleToMemory memory_formatter(buffer, buffer_size); - LogBlock lb; - Disassemble(start, end, &memory_formatter); -#else - UNREACHABLE(); -#endif - } - - // Decodes one instruction. - // Writes a hexadecimal representation into the hex_buffer and a - // human-readable representation into the human_buffer. - // Writes the length of the decoded instruction in bytes in out_instr_len. - static void DecodeInstruction(char* hex_buffer, - intptr_t hex_size, - char* human_buffer, - intptr_t human_size, - int* out_instr_len, - const Bytecode& bytecode, - Object** object, - uword pc); - - static void Disassemble(const Function& function); - - private: - static const int kHexadecimalBufferSize = 32; - static const int kUserReadableBufferSize = 256; -}; - -} // namespace dart - -#endif // !defined(DART_PRECOMPILED_RUNTIME) - -#endif // RUNTIME_VM_COMPILER_ASSEMBLER_DISASSEMBLER_KBC_H_ diff --git a/runtime/vm/compiler/assembler/object_pool_builder.h b/runtime/vm/compiler/assembler/object_pool_builder.h index de9749df05f..2bc2add1caa 100644 --- a/runtime/vm/compiler/assembler/object_pool_builder.h +++ b/runtime/vm/compiler/assembler/object_pool_builder.h @@ -30,7 +30,6 @@ struct ObjectPoolBuilderEntry { kImmediate, kNativeFunction, kNativeFunctionWrapper, - kNativeEntryData, }; using TypeBits = BitField; diff --git a/runtime/vm/compiler/backend/flow_graph.h b/runtime/vm/compiler/backend/flow_graph.h index 50ea5ecabb5..a288e47a2db 100644 --- a/runtime/vm/compiler/backend/flow_graph.h +++ b/runtime/vm/compiler/backend/flow_graph.h @@ -162,10 +162,6 @@ class FlowGraph : public ZoneAllocated { } intptr_t CurrentContextEnvIndex() const { - if (function().HasBytecode()) { - return -1; - } - return EnvIndex(parsed_function().current_context_var()); } diff --git a/runtime/vm/compiler/backend/il.cc b/runtime/vm/compiler/backend/il.cc index 43937b008cd..fafae7a1edc 100644 --- a/runtime/vm/compiler/backend/il.cc +++ b/runtime/vm/compiler/backend/il.cc @@ -775,8 +775,7 @@ static intptr_t Usage(const Function& function) { // 'function' is queued for optimized compilation count = FLAG_optimization_counter_threshold; } else { - // 'function' is queued for unoptimized compilation - count = FLAG_compilation_counter_threshold; + count = 0; } } else if (Code::IsOptimized(function.CurrentCode())) { // 'function' was optimized and stopped counting @@ -4834,10 +4833,8 @@ void InstanceCallInstr::EmitNativeCode(FlowGraphCompiler* compiler) { UpdateReceiverSminess(zone); - if ((compiler->is_optimizing() || compiler->function().HasBytecode()) && - HasICData()) { - ASSERT(HasICData()); - if (compiler->is_optimizing() && (ic_data()->NumberOfUsedChecks() > 0)) { + if (compiler->is_optimizing() && HasICData()) { + if (ic_data()->NumberOfUsedChecks() > 0) { const ICData& unary_ic_data = ICData::ZoneHandle(zone, ic_data()->AsUnaryClassChecks()); compiler->GenerateInstanceCall(deopt_id(), token_pos(), locs(), diff --git a/runtime/vm/compiler/backend/il_test.cc b/runtime/vm/compiler/backend/il_test.cc index a07557febdf..478868696e3 100644 --- a/runtime/vm/compiler/backend/il_test.cc +++ b/runtime/vm/compiler/backend/il_test.cc @@ -174,29 +174,14 @@ ISOLATE_UNIT_TEST_CASE(IRTest_InitializingStores) { // which enables us to remove more stores. std::vector expected_stores_jit; std::vector expected_stores_aot; - if (root_library.is_declared_in_bytecode()) { - // Bytecode flow graph builder doesn't provide readable - // variable names for captured variables. Also, bytecode may omit - // stores of context parent in certain cases. - expected_stores_jit.insert( - expected_stores_jit.end(), - {":context_var0", "Context.parent", ":context_var0", - "Closure.function_type_arguments", "Closure.function", - "Closure.context"}); - expected_stores_aot.insert( - expected_stores_aot.end(), - {":context_var0", "Closure.function_type_arguments", "Closure.function", - "Closure.context"}); - } else { - // These expectations are for AST-based flow graph builder. - expected_stores_jit.insert(expected_stores_jit.end(), - {"value", "Context.parent", "Context.parent", - "value", "Closure.function_type_arguments", - "Closure.function", "Closure.context"}); - expected_stores_aot.insert(expected_stores_aot.end(), - {"value", "Closure.function_type_arguments", - "Closure.function", "Closure.context"}); - } + + expected_stores_jit.insert(expected_stores_jit.end(), + {"value", "Context.parent", "Context.parent", + "value", "Closure.function_type_arguments", + "Closure.function", "Closure.context"}); + expected_stores_aot.insert(expected_stores_aot.end(), + {"value", "Closure.function_type_arguments", + "Closure.function", "Closure.context"}); RunInitializingStoresTest(root_library, "f4", CompilerPass::kJIT, expected_stores_jit); diff --git a/runtime/vm/compiler/backend/il_test_helper.cc b/runtime/vm/compiler/backend/il_test_helper.cc index f4d002b2040..1a514be8491 100644 --- a/runtime/vm/compiler/backend/il_test_helper.cc +++ b/runtime/vm/compiler/backend/il_test_helper.cc @@ -71,12 +71,6 @@ TypeParameterPtr GetFunctionTypeParameter(const Function& fun, } ObjectPtr Invoke(const Library& lib, const char* name) { - // These tests rely on running unoptimized code to collect type feedback. The - // interpreter does not collect type feedback for interface calls, so set - // compilation threshold to 0 in order to compile invoked function - // immediately and execute compiled code. - SetFlagScope sfs(&FLAG_compilation_counter_threshold, 0); - Thread* thread = Thread::Current(); Dart_Handle api_lib = Api::NewHandle(thread, lib.raw()); Dart_Handle result; diff --git a/runtime/vm/compiler/backend/inliner_test.cc b/runtime/vm/compiler/backend/inliner_test.cc index 081e7949b92..9a53a7b3bcc 100644 --- a/runtime/vm/compiler/backend/inliner_test.cc +++ b/runtime/vm/compiler/backend/inliner_test.cc @@ -216,74 +216,42 @@ ISOLATE_UNIT_TEST_CASE(Inliner_List_generate) { ILMatcher cursor(flow_graph, entry, /*trace=*/true, ParallelMovesHandling::kSkip); - if (function.is_declared_in_bytecode()) { - RELEASE_ASSERT(cursor.TryMatch({ - kMoveGlob, - kMatchAndMoveCreateArray, - kWordSize == 8 ? kMatchAndMoveUnboxInt64 : kNop, - kMatchAndMoveGoto, + Instruction* unbox1 = nullptr; + Instruction* unbox2 = nullptr; - // Loop header - kMatchAndMoveJoinEntry, - kMatchAndMoveCheckStackOverflow, - kMatchAndMoveUnboxInt64, - kMatchAndMoveBranchTrue, + RELEASE_ASSERT(cursor.TryMatch({ + kMoveGlob, + kMatchAndMoveCreateArray, + kMatchAndMoveUnboxInt64, + {kMoveAny, &unbox1}, + {kMoveAny, &unbox2}, + kMatchAndMoveGoto, - // Loop body - kMatchAndMoveTargetEntry, - kMatchAndMoveGenericCheckBound, - kMatchAndMoveStoreIndexed, - kMatchAndMoveCheckedSmiOp, - kMatchAndMoveGoto, + // Loop header + kMatchAndMoveJoinEntry, + kMatchAndMoveCheckStackOverflow, + kMatchAndMoveBranchTrue, - // Loop header once again - kMatchAndMoveJoinEntry, - kMatchAndMoveCheckStackOverflow, - kMatchAndMoveUnboxInt64, - kMatchAndMoveBranchFalse, + // Loop body + kMatchAndMoveTargetEntry, + kWordSize == 4 ? kMatchAndMoveBoxInt64 : kNop, + kMatchAndMoveBoxInt64, + kMatchAndMoveStoreIndexed, + kMatchAndMoveBinaryInt64Op, + kMatchAndMoveGoto, - // After loop - kMatchAndMoveTargetEntry, - kMatchReturn, - })); - } else { - Instruction* unbox1 = nullptr; - Instruction* unbox2 = nullptr; + // Loop header once again + kMatchAndMoveJoinEntry, + kMatchAndMoveCheckStackOverflow, + kMatchAndMoveBranchFalse, - RELEASE_ASSERT(cursor.TryMatch({ - kMoveGlob, - kMatchAndMoveCreateArray, - kMatchAndMoveUnboxInt64, - {kMoveAny, &unbox1}, - {kMoveAny, &unbox2}, - kMatchAndMoveGoto, + // After loop + kMatchAndMoveTargetEntry, + kMatchReturn, + })); - // Loop header - kMatchAndMoveJoinEntry, - kMatchAndMoveCheckStackOverflow, - kMatchAndMoveBranchTrue, - - // Loop body - kMatchAndMoveTargetEntry, - kWordSize == 4 ? kMatchAndMoveBoxInt64 : kNop, - kMatchAndMoveBoxInt64, - kMatchAndMoveStoreIndexed, - kMatchAndMoveBinaryInt64Op, - kMatchAndMoveGoto, - - // Loop header once again - kMatchAndMoveJoinEntry, - kMatchAndMoveCheckStackOverflow, - kMatchAndMoveBranchFalse, - - // After loop - kMatchAndMoveTargetEntry, - kMatchReturn, - })); - - EXPECT(unbox1->IsUnboxedConstant() || unbox1->IsUnboxInt64()); - EXPECT(unbox2->IsUnboxedConstant() || unbox2->IsUnboxInt64()); - } + EXPECT(unbox1->IsUnboxedConstant() || unbox1->IsUnboxInt64()); + EXPECT(unbox2->IsUnboxedConstant() || unbox2->IsUnboxInt64()); } #endif // defined(DART_PRECOMPILER) diff --git a/runtime/vm/compiler/backend/redundancy_elimination_test.cc b/runtime/vm/compiler/backend/redundancy_elimination_test.cc index c1d2dd61068..bc3b72fda92 100644 --- a/runtime/vm/compiler/backend/redundancy_elimination_test.cc +++ b/runtime/vm/compiler/backend/redundancy_elimination_test.cc @@ -13,7 +13,6 @@ #include "vm/compiler/backend/loops.h" #include "vm/compiler/backend/type_propagator.h" #include "vm/compiler/compiler_pass.h" -#include "vm/compiler/frontend/bytecode_reader.h" #include "vm/compiler/frontend/kernel_to_il.h" #include "vm/compiler/jit/jit_call_specializer.h" #include "vm/flags.h" @@ -60,35 +59,6 @@ static void FlattenScopeIntoEnvironment(FlowGraph* graph, } } -#if !defined(PRODUCT) -void PopulateEnvironmentFromBytecodeLocalVariables( - const Function& function, - FlowGraph* graph, - GrowableArray* env) { - const auto& bytecode = Bytecode::Handle(function.bytecode()); - ASSERT(!bytecode.IsNull()); - - kernel::BytecodeLocalVariablesIterator iter(Thread::Current()->zone(), - bytecode); - while (iter.MoveNext()) { - if (iter.IsVariableDeclaration() && !iter.IsCaptured()) { - LocalVariable* const var = new LocalVariable( - TokenPosition::kNoSource, TokenPosition::kNoSource, - String::ZoneHandle(graph->zone(), iter.Name()), - AbstractType::ZoneHandle(graph->zone(), iter.Type())); - if (iter.Index() < 0) { // Parameter. - var->set_index(VariableIndex(-iter.Index() - kKBCParamEndSlotFromFp)); - } else { - var->set_index(VariableIndex(-iter.Index())); - } - const intptr_t env_index = graph->EnvIndex(var); - env->EnsureLength(env_index + 1, nullptr); - (*env)[env_index] = var; - } - } -} -#endif - // Run TryCatchAnalyzer optimization on the function foo from the given script // and check that the only variables from the given list are synchronized // on catch entry. @@ -118,17 +88,7 @@ static void TryCatchOptimizerTest( auto scope = graph->parsed_function().scope(); GrowableArray env; - if (function.is_declared_in_bytecode()) { -#if defined(PRODUCT) - // In product mode information about local variables is not retained in - // bytecode, so we can't find variables by names. - return; -#else - PopulateEnvironmentFromBytecodeLocalVariables(function, graph, &env); -#endif - } else { - FlattenScopeIntoEnvironment(graph, scope, &env); - } + FlattenScopeIntoEnvironment(graph, scope, &env); for (intptr_t i = 0; i < env.length(); i++) { bool found = false; diff --git a/runtime/vm/compiler/compiler_sources.gni b/runtime/vm/compiler/compiler_sources.gni index 0efb336dfe4..dd1d2fa878e 100644 --- a/runtime/vm/compiler/compiler_sources.gni +++ b/runtime/vm/compiler/compiler_sources.gni @@ -111,14 +111,6 @@ compiler_sources = [ "ffi/recognized_method.h", "frontend/base_flow_graph_builder.cc", "frontend/base_flow_graph_builder.h", - "frontend/bytecode_fingerprints.cc", - "frontend/bytecode_fingerprints.h", - "frontend/bytecode_flow_graph_builder.cc", - "frontend/bytecode_flow_graph_builder.h", - "frontend/bytecode_reader.cc", - "frontend/bytecode_reader.h", - "frontend/bytecode_scope_builder.cc", - "frontend/bytecode_scope_builder.h", "frontend/constant_reader.cc", "frontend/constant_reader.h", "frontend/flow_graph_builder.cc", @@ -210,7 +202,5 @@ disassembler_sources = [ "assembler/disassembler.h", "assembler/disassembler_arm.cc", "assembler/disassembler_arm64.cc", - "assembler/disassembler_kbc.cc", - "assembler/disassembler_kbc.h", "assembler/disassembler_x86.cc", ] diff --git a/runtime/vm/compiler/compiler_state.h b/runtime/vm/compiler/compiler_state.h index c394822d39e..913e36b6d0c 100644 --- a/runtime/vm/compiler/compiler_state.h +++ b/runtime/vm/compiler/compiler_state.h @@ -69,15 +69,6 @@ class CompilerState : public ThreadStackResource { // Create a dummy list of local variables representing a context object // with the given number of captured variables and given ID. - // - // Used during bytecode to IL translation because AllocateContext and - // CloneContext IL instructions need a list of local varaibles and bytecode - // does not record this information. - // - // TODO(vegorov): create context classes for distinct context IDs and - // populate them with slots without creating variables. - // Beware that context_id is satured at 8-bits, so multiple contexts may - // share id 255. const ZoneGrowableArray& GetDummyContextSlots( intptr_t context_id, intptr_t num_context_slots); @@ -85,16 +76,8 @@ class CompilerState : public ThreadStackResource { // Create a dummy LocalVariable that represents a captured local variable // at the given index in the context with given ID. // - // Used during bytecode to IL translation because StoreInstanceField and - // LoadField IL instructions need Slot, which can only be created from a - // LocalVariable. - // // This function returns the same variable when it is called with the // same index. - // - // TODO(vegorov): disambiguate slots for different context IDs. - // Beware that context_id is saturated at 8-bits, so multiple contexts may - // share id 255. LocalVariable* GetDummyCapturedVariable(intptr_t context_id, intptr_t index); bool is_aot() const { return is_aot_; } @@ -115,8 +98,7 @@ class CompilerState : public ThreadStackResource { // Cache for Slot objects created during compilation (see slot.h). SlotCache* slot_cache_ = nullptr; - // Caches for dummy LocalVariables and context Slots created during bytecode - // to IL translation. + // Caches for dummy LocalVariables and context Slots. ZoneGrowableArray*>* dummy_slots_ = nullptr; ZoneGrowableArray* dummy_captured_vars_ = nullptr; diff --git a/runtime/vm/compiler/frontend/base_flow_graph_builder.h b/runtime/vm/compiler/frontend/base_flow_graph_builder.h index 673375a7013..790ac1a82cb 100644 --- a/runtime/vm/compiler/frontend/base_flow_graph_builder.h +++ b/runtime/vm/compiler/frontend/base_flow_graph_builder.h @@ -465,7 +465,6 @@ class BaseFlowGraphBuilder { const Array& saved_args_desc_array_; friend class StreamingFlowGraphBuilder; - friend class BytecodeFlowGraphBuilder; private: DISALLOW_COPY_AND_ASSIGN(BaseFlowGraphBuilder); diff --git a/runtime/vm/compiler/frontend/bytecode_fingerprints.cc b/runtime/vm/compiler/frontend/bytecode_fingerprints.cc deleted file mode 100644 index 78d621e373a..00000000000 --- a/runtime/vm/compiler/frontend/bytecode_fingerprints.cc +++ /dev/null @@ -1,207 +0,0 @@ -// Copyright (c) 2019, the Dart project authors. Please see the AUTHORS file -// for details. All rights reserved. Use of this source code is governed by a -// BSD-style license that can be found in the LICENSE file. - -#include "vm/compiler/frontend/bytecode_fingerprints.h" - -#include "vm/compiler/frontend/bytecode_reader.h" -#include "vm/constants_kbc.h" -#include "vm/hash.h" - -namespace dart { -namespace kernel { - -static uint32_t CombineObject(uint32_t hash, const Object& obj) { - if (obj.IsAbstractType()) { - return CombineHashes(hash, AbstractType::Cast(obj).Hash()); - } else if (obj.IsClass()) { - return CombineHashes(hash, Class::Cast(obj).id()); - } else if (obj.IsFunction()) { - return CombineHashes( - hash, AbstractType::Handle(Function::Cast(obj).result_type()).Hash()); - } else if (obj.IsField()) { - return CombineHashes(hash, - AbstractType::Handle(Field::Cast(obj).type()).Hash()); - } else { - return CombineHashes(hash, static_cast(obj.GetClassId())); - } -} - -typedef uint32_t (*Fp)(uint32_t fp, - const KBCInstr* instr, - const ObjectPool& pool, - int32_t value); - -static uint32_t Fp___(uint32_t fp, - const KBCInstr* instr, - const ObjectPool& pool, - int32_t value) { - return fp; -} - -static uint32_t Fptgt(uint32_t fp, - const KBCInstr* instr, - const ObjectPool& pool, - int32_t value) { - return CombineHashes(fp, value); -} - -static uint32_t Fplit(uint32_t fp, - const KBCInstr* instr, - const ObjectPool& pool, - int32_t value) { - return CombineObject(fp, Object::Handle(pool.ObjectAt(value))); -} - -static uint32_t Fpreg(uint32_t fp, - const KBCInstr* instr, - const ObjectPool& pool, - int32_t value) { - return CombineHashes(fp, value); -} - -static uint32_t Fpxeg(uint32_t fp, - const KBCInstr* instr, - const ObjectPool& pool, - int32_t value) { - return CombineHashes(fp, value); -} - -static uint32_t Fpnum(uint32_t fp, - const KBCInstr* instr, - const ObjectPool& pool, - int32_t value) { - return CombineHashes(fp, value); -} - -static uint32_t Fingerprint0(uint32_t fp, - const KBCInstr* instr, - const ObjectPool& pool, - Fp op1, - Fp op2, - Fp op3) { - return fp; -} - -static uint32_t FingerprintA(uint32_t fp, - const KBCInstr* instr, - const ObjectPool& pool, - Fp op1, - Fp op2, - Fp op3) { - fp = op1(fp, instr, pool, KernelBytecode::DecodeA(instr)); - return fp; -} - -static uint32_t FingerprintD(uint32_t fp, - const KBCInstr* instr, - const ObjectPool& pool, - Fp op1, - Fp op2, - Fp op3) { - fp = op1(fp, instr, pool, KernelBytecode::DecodeD(instr)); - return fp; -} - -static uint32_t FingerprintX(uint32_t fp, - const KBCInstr* instr, - const ObjectPool& pool, - Fp op1, - Fp op2, - Fp op3) { - fp = op1(fp, instr, pool, KernelBytecode::DecodeX(instr)); - return fp; -} - -static uint32_t FingerprintT(uint32_t fp, - const KBCInstr* instr, - const ObjectPool& pool, - Fp op1, - Fp op2, - Fp op3) { - fp = op1(fp, instr, pool, KernelBytecode::DecodeT(instr)); - return fp; -} - -static uint32_t FingerprintA_E(uint32_t fp, - const KBCInstr* instr, - const ObjectPool& pool, - Fp op1, - Fp op2, - Fp op3) { - fp = op1(fp, instr, pool, KernelBytecode::DecodeA(instr)); - fp = op2(fp, instr, pool, KernelBytecode::DecodeE(instr)); - return fp; -} - -static uint32_t FingerprintA_Y(uint32_t fp, - const KBCInstr* instr, - const ObjectPool& pool, - Fp op1, - Fp op2, - Fp op3) { - fp = op1(fp, instr, pool, KernelBytecode::DecodeA(instr)); - fp = op2(fp, instr, pool, KernelBytecode::DecodeY(instr)); - return fp; -} - -static uint32_t FingerprintD_F(uint32_t fp, - const KBCInstr* instr, - const ObjectPool& pool, - Fp op1, - Fp op2, - Fp op3) { - fp = op1(fp, instr, pool, KernelBytecode::DecodeD(instr)); - fp = op2(fp, instr, pool, KernelBytecode::DecodeF(instr)); - return fp; -} - -static uint32_t FingerprintA_B_C(uint32_t fp, - const KBCInstr* instr, - const ObjectPool& pool, - Fp op1, - Fp op2, - Fp op3) { - fp = op1(fp, instr, pool, KernelBytecode::DecodeA(instr)); - fp = op2(fp, instr, pool, KernelBytecode::DecodeB(instr)); - fp = op3(fp, instr, pool, KernelBytecode::DecodeC(instr)); - return fp; -} - -uint32_t BytecodeFingerprintHelper::CalculateFunctionFingerprint( - const Function& function) { - ASSERT(function.is_declared_in_bytecode()); - const intptr_t kHashBits = 30; - uint32_t fp = 0; - fp = CombineHashes(fp, String::Handle(function.UserVisibleName()).Hash()); - if (function.is_abstract()) { - return FinalizeHash(fp, kHashBits); - } - if (!function.HasBytecode()) { - kernel::BytecodeReader::ReadFunctionBytecode(Thread::Current(), function); - } - const Bytecode& code = Bytecode::Handle(function.bytecode()); - const ObjectPool& pool = ObjectPool::Handle(code.object_pool()); - const KBCInstr* const start = - reinterpret_cast(code.instructions()); - for (const KBCInstr* instr = start; (instr - start) < code.Size(); - instr = KernelBytecode::Next(instr)) { - const KernelBytecode::Opcode opcode = KernelBytecode::DecodeOpcode(instr); - fp = CombineHashes(fp, opcode); - switch (opcode) { -#define FINGERPRINT_BYTECODE(name, encoding, kind, op1, op2, op3) \ - case KernelBytecode::k##name: \ - fp = Fingerprint##encoding(fp, instr, pool, Fp##op1, Fp##op2, Fp##op3); \ - break; - KERNEL_BYTECODES_LIST(FINGERPRINT_BYTECODE) -#undef FINGERPRINT_BYTECODE - default: - UNREACHABLE(); - } - } - - return FinalizeHash(fp, kHashBits); -} - -} // namespace kernel -} // namespace dart diff --git a/runtime/vm/compiler/frontend/bytecode_fingerprints.h b/runtime/vm/compiler/frontend/bytecode_fingerprints.h deleted file mode 100644 index 78dbcff6454..00000000000 --- a/runtime/vm/compiler/frontend/bytecode_fingerprints.h +++ /dev/null @@ -1,26 +0,0 @@ -// Copyright (c) 2019, the Dart project authors. Please see the AUTHORS file -// for details. All rights reserved. Use of this source code is governed by a -// BSD-style license that can be found in the LICENSE file. - -#ifndef RUNTIME_VM_COMPILER_FRONTEND_BYTECODE_FINGERPRINTS_H_ -#define RUNTIME_VM_COMPILER_FRONTEND_BYTECODE_FINGERPRINTS_H_ - -#if defined(DART_PRECOMPILED_RUNTIME) -#error "AOT runtime should not use compiler sources (including header files)" -#endif // defined(DART_PRECOMPILED_RUNTIME) - -#include "platform/allocation.h" -#include "vm/object.h" - -namespace dart { -namespace kernel { - -class BytecodeFingerprintHelper : public AllStatic { - public: - static uint32_t CalculateFunctionFingerprint(const Function& func); -}; - -} // namespace kernel -} // namespace dart - -#endif // RUNTIME_VM_COMPILER_FRONTEND_BYTECODE_FINGERPRINTS_H_ diff --git a/runtime/vm/compiler/frontend/bytecode_flow_graph_builder.cc b/runtime/vm/compiler/frontend/bytecode_flow_graph_builder.cc deleted file mode 100644 index 41af858f1b9..00000000000 --- a/runtime/vm/compiler/frontend/bytecode_flow_graph_builder.cc +++ /dev/null @@ -1,2375 +0,0 @@ -// Copyright (c) 2018, the Dart project authors. Please see the AUTHORS file -// for details. All rights reserved. Use of this source code is governed by a -// BSD-style license that can be found in the LICENSE file. - -#include "vm/compiler/frontend/bytecode_flow_graph_builder.h" - -#include "vm/compiler/backend/il_printer.h" -#include "vm/compiler/ffi/callback.h" -#include "vm/compiler/frontend/bytecode_reader.h" -#include "vm/compiler/frontend/prologue_builder.h" -#include "vm/compiler/jit/compiler.h" -#include "vm/object_store.h" -#include "vm/stack_frame.h" -#include "vm/stack_frame_kbc.h" - -#define B (flow_graph_builder_) -#define Z (zone_) - -namespace dart { - -DEFINE_FLAG(bool, - print_flow_graph_from_bytecode, - false, - "Print flow graph constructed from bytecode"); - -namespace kernel { - -BytecodeFlowGraphBuilder::Operand BytecodeFlowGraphBuilder::DecodeOperandA() { - if (is_generating_interpreter()) { - UNIMPLEMENTED(); // TODO(alexmarkov): interpreter - } else { - intptr_t value = KernelBytecode::DecodeA(bytecode_instr_); - return Operand(value); - } -} - -BytecodeFlowGraphBuilder::Operand BytecodeFlowGraphBuilder::DecodeOperandB() { - if (is_generating_interpreter()) { - UNIMPLEMENTED(); // TODO(alexmarkov): interpreter - } else { - intptr_t value = KernelBytecode::DecodeB(bytecode_instr_); - return Operand(value); - } -} - -BytecodeFlowGraphBuilder::Operand BytecodeFlowGraphBuilder::DecodeOperandC() { - if (is_generating_interpreter()) { - UNIMPLEMENTED(); // TODO(alexmarkov): interpreter - } else { - intptr_t value = KernelBytecode::DecodeC(bytecode_instr_); - return Operand(value); - } -} - -BytecodeFlowGraphBuilder::Operand BytecodeFlowGraphBuilder::DecodeOperandD() { - if (is_generating_interpreter()) { - UNIMPLEMENTED(); // TODO(alexmarkov): interpreter - } else { - intptr_t value = KernelBytecode::DecodeD(bytecode_instr_); - return Operand(value); - } -} - -BytecodeFlowGraphBuilder::Operand BytecodeFlowGraphBuilder::DecodeOperandE() { - if (is_generating_interpreter()) { - UNIMPLEMENTED(); // TODO(alexmarkov): interpreter - } else { - intptr_t value = KernelBytecode::DecodeE(bytecode_instr_); - return Operand(value); - } -} - -BytecodeFlowGraphBuilder::Operand BytecodeFlowGraphBuilder::DecodeOperandF() { - if (is_generating_interpreter()) { - UNIMPLEMENTED(); // TODO(alexmarkov): interpreter - } else { - intptr_t value = KernelBytecode::DecodeF(bytecode_instr_); - return Operand(value); - } -} - -BytecodeFlowGraphBuilder::Operand BytecodeFlowGraphBuilder::DecodeOperandX() { - if (is_generating_interpreter()) { - UNIMPLEMENTED(); // TODO(alexmarkov): interpreter - } else { - intptr_t value = KernelBytecode::DecodeX(bytecode_instr_); - return Operand(value); - } -} - -BytecodeFlowGraphBuilder::Operand BytecodeFlowGraphBuilder::DecodeOperandY() { - if (is_generating_interpreter()) { - UNIMPLEMENTED(); // TODO(alexmarkov): interpreter - } else { - intptr_t value = KernelBytecode::DecodeY(bytecode_instr_); - return Operand(value); - } -} - -BytecodeFlowGraphBuilder::Operand BytecodeFlowGraphBuilder::DecodeOperandT() { - if (is_generating_interpreter()) { - UNIMPLEMENTED(); // TODO(alexmarkov): interpreter - } else { - intptr_t value = KernelBytecode::DecodeT(bytecode_instr_); - return Operand(value); - } -} - -BytecodeFlowGraphBuilder::Constant BytecodeFlowGraphBuilder::ConstantAt( - Operand entry_index, - intptr_t add_index) { - if (is_generating_interpreter()) { - UNIMPLEMENTED(); // TODO(alexmarkov): interpreter - } else { - const Object& value = Object::ZoneHandle( - Z, object_pool_.ObjectAt(entry_index.value() + add_index)); - return Constant(Z, value); - } -} - -void BytecodeFlowGraphBuilder::PushConstant(Constant constant) { - if (is_generating_interpreter()) { - B->Push(constant.definition()); - } else { - code_ += B->Constant(constant.value()); - } -} - -BytecodeFlowGraphBuilder::Constant BytecodeFlowGraphBuilder::PopConstant() { - if (is_generating_interpreter()) { - UNIMPLEMENTED(); // TODO(alexmarkov): interpreter - } else { - ASSERT(!IsStackEmpty()); - const Object& value = B->stack_->definition()->AsConstant()->value(); - code_ += B->Drop(); - return Constant(Z, value); - } -} - -void BytecodeFlowGraphBuilder::LoadStackSlots(intptr_t num_slots) { - if (is_generating_interpreter()) { - UNIMPLEMENTED(); // TODO(alexmarkov): interpreter - } - - ASSERT(GetStackDepth() >= num_slots); -} - -void BytecodeFlowGraphBuilder::AllocateLocalVariables( - Operand frame_size, - intptr_t num_param_locals) { - if (is_generating_interpreter()) { - UNIMPLEMENTED(); // TODO(alexmarkov): interpreter - } else { - ASSERT(local_vars_.is_empty()); - - const intptr_t num_bytecode_locals = frame_size.value(); - ASSERT(num_bytecode_locals >= 0); - - intptr_t num_locals = num_bytecode_locals; - if (exception_var_ != nullptr) { - ++num_locals; - } - if (stacktrace_var_ != nullptr) { - ++num_locals; - } - if (scratch_var_ != nullptr) { - ++num_locals; - } - if (parsed_function()->has_arg_desc_var()) { - ++num_locals; - } - if (parsed_function()->has_entry_points_temp_var()) { - ++num_locals; - } - - if (num_locals == 0) { - return; - } - - local_vars_.EnsureLength(num_bytecode_locals, nullptr); - intptr_t idx = num_param_locals; - for (; idx < num_bytecode_locals; ++idx) { - String& name = String::ZoneHandle( - Z, Symbols::NewFormatted(thread(), "var%" Pd, idx)); - LocalVariable* local = new (Z) - LocalVariable(TokenPosition::kNoSource, TokenPosition::kNoSource, - name, Object::dynamic_type()); - local->set_index(VariableIndex(-idx)); - local_vars_[idx] = local; - } - - if (exception_var_ != nullptr) { - exception_var_->set_index(VariableIndex(-idx)); - ++idx; - } - if (stacktrace_var_ != nullptr) { - stacktrace_var_->set_index(VariableIndex(-idx)); - ++idx; - } - if (scratch_var_ != nullptr) { - scratch_var_->set_index(VariableIndex(-idx)); - ++idx; - } - if (parsed_function()->has_arg_desc_var()) { - parsed_function()->arg_desc_var()->set_index(VariableIndex(-idx)); - ++idx; - } - if (parsed_function()->has_entry_points_temp_var()) { - parsed_function()->entry_points_temp_var()->set_index( - VariableIndex(-idx)); - ++idx; - } - ASSERT(idx == num_locals); - - ASSERT(parsed_function()->scope() == nullptr); - parsed_function()->AllocateBytecodeVariables(num_locals); - } -} - -LocalVariable* BytecodeFlowGraphBuilder::AllocateParameter( - intptr_t param_index, - VariableIndex var_index) { - const String& name = - String::ZoneHandle(Z, function().ParameterNameAt(param_index)); - const AbstractType& type = - AbstractType::ZoneHandle(Z, function().ParameterTypeAt(param_index)); - - CompileType* param_type = nullptr; - if (!inferred_types_attribute_.IsNull()) { - // Parameter types are assigned to synthetic PCs = -N,..,-1 - // where N is number of parameters. - const intptr_t pc = -function().NumParameters() + param_index; - // Search from the beginning as parameters may be declared in arbitrary - // order. - inferred_types_index_ = 0; - const InferredTypeMetadata inferred_type = GetInferredType(pc); - if (!inferred_type.IsTrivial()) { - param_type = new (Z) CompileType(inferred_type.ToCompileType(Z)); - } - } - - LocalVariable* param_var = - new (Z) LocalVariable(TokenPosition::kNoSource, TokenPosition::kNoSource, - name, type, param_type); - param_var->set_index(var_index); - - if (!function().IsNonImplicitClosureFunction() && - (function().is_static() || - ((function().name() != Symbols::Call().raw()) && - !parsed_function()->IsCovariantParameter(param_index) && - !parsed_function()->IsGenericCovariantImplParameter(param_index)))) { - param_var->set_type_check_mode(LocalVariable::kTypeCheckedByCaller); - } - - if (var_index.value() <= 0) { - local_vars_[-var_index.value()] = param_var; - } - - return param_var; -} - -void BytecodeFlowGraphBuilder::AllocateFixedParameters() { - if (is_generating_interpreter()) { - return; - } - - ASSERT(!function().HasOptionalParameters()); - - const intptr_t num_fixed_params = function().num_fixed_parameters(); - auto parameters = - new (Z) ZoneGrowableArray(Z, num_fixed_params); - - for (intptr_t i = 0; i < num_fixed_params; ++i) { - LocalVariable* param_var = - AllocateParameter(i, VariableIndex(num_fixed_params - i)); - parameters->Add(param_var); - } - - parsed_function()->SetRawParameters(parameters); -} - -const KBCInstr* -BytecodeFlowGraphBuilder::AllocateParametersAndLocalsForEntryOptional() { - ASSERT(KernelBytecode::IsEntryOptionalOpcode(bytecode_instr_)); - - const intptr_t num_fixed_params = DecodeOperandA().value(); - const intptr_t num_opt_pos_params = DecodeOperandB().value(); - const intptr_t num_opt_named_params = DecodeOperandC().value(); - - ASSERT(num_fixed_params == function().num_fixed_parameters()); - ASSERT(num_opt_pos_params == function().NumOptionalPositionalParameters()); - ASSERT(num_opt_named_params == function().NumOptionalNamedParameters()); - - ASSERT((num_opt_pos_params == 0) || (num_opt_named_params == 0)); - const intptr_t num_load_const = num_opt_pos_params + 2 * num_opt_named_params; - - const KBCInstr* instr = KernelBytecode::Next(bytecode_instr_); - const KBCInstr* frame_instr = instr; - for (intptr_t i = 0; i < num_load_const; ++i) { - frame_instr = KernelBytecode::Next(frame_instr); - } - ASSERT(KernelBytecode::IsFrameOpcode(frame_instr)); - const intptr_t num_extra_locals = KernelBytecode::DecodeD(frame_instr); - const intptr_t num_params = - num_fixed_params + num_opt_pos_params + num_opt_named_params; - const intptr_t total_locals = num_params + num_extra_locals; - - AllocateLocalVariables(Operand(total_locals), num_params); - - ZoneGrowableArray* default_values = - new (Z) ZoneGrowableArray( - Z, num_opt_pos_params + num_opt_named_params); - ZoneGrowableArray* raw_parameters = - new (Z) ZoneGrowableArray(Z, num_params); - - intptr_t param = 0; - for (; param < num_fixed_params; ++param) { - LocalVariable* param_var = AllocateParameter(param, VariableIndex(-param)); - raw_parameters->Add(param_var); - } - - for (intptr_t i = 0; i < num_opt_pos_params; ++i, ++param) { - const KBCInstr* load_value_instr = instr; - instr = KernelBytecode::Next(instr); - ASSERT(KernelBytecode::IsLoadConstantOpcode(load_value_instr)); - ASSERT(KernelBytecode::DecodeA(load_value_instr) == param); - const Object& default_value = - ConstantAt(Operand(KernelBytecode::DecodeE(load_value_instr))).value(); - - LocalVariable* param_var = AllocateParameter(param, VariableIndex(-param)); - raw_parameters->Add(param_var); - default_values->Add( - &Instance::ZoneHandle(Z, Instance::RawCast(default_value.raw()))); - } - - if (num_opt_named_params > 0) { - default_values->EnsureLength(num_opt_named_params, nullptr); - raw_parameters->EnsureLength(num_params, nullptr); - - ASSERT(scratch_var_ != nullptr); - - for (intptr_t i = 0; i < num_opt_named_params; ++i, ++param) { - const KBCInstr* load_name_instr = instr; - const KBCInstr* load_value_instr = KernelBytecode::Next(load_name_instr); - instr = KernelBytecode::Next(load_value_instr); - ASSERT(KernelBytecode::IsLoadConstantOpcode(load_name_instr)); - ASSERT(KernelBytecode::IsLoadConstantOpcode(load_value_instr)); - const String& param_name = String::Cast( - ConstantAt(Operand(KernelBytecode::DecodeE(load_name_instr))) - .value()); - ASSERT(param_name.IsSymbol()); - const Object& default_value = - ConstantAt(Operand(KernelBytecode::DecodeE(load_value_instr))) - .value(); - - intptr_t param_index = num_fixed_params; - for (; param_index < num_params; ++param_index) { - if (function().ParameterNameAt(param_index) == param_name.raw()) { - break; - } - } - ASSERT(param_index < num_params); - - ASSERT(default_values->At(param_index - num_fixed_params) == nullptr); - (*default_values)[param_index - num_fixed_params] = - &Instance::ZoneHandle(Z, Instance::RawCast(default_value.raw())); - - const intptr_t local_index = KernelBytecode::DecodeA(load_name_instr); - ASSERT(local_index == KernelBytecode::DecodeA(load_value_instr)); - - LocalVariable* param_var = - AllocateParameter(param_index, VariableIndex(-param)); - ASSERT(raw_parameters->At(param_index) == nullptr); - (*raw_parameters)[param_index] = param_var; - } - } - - ASSERT(instr == frame_instr); - - parsed_function()->set_default_parameter_values(default_values); - parsed_function()->SetRawParameters(raw_parameters); - - return KernelBytecode::Next(frame_instr); -} - -LocalVariable* BytecodeFlowGraphBuilder::LocalVariableAt(intptr_t local_index) { - ASSERT(!is_generating_interpreter()); - if (local_index < 0) { - // Parameter - ASSERT(!function().HasOptionalParameters()); - const intptr_t param_index = local_index + - function().num_fixed_parameters() + - kKBCParamEndSlotFromFp; - ASSERT((0 <= param_index) && - (param_index < function().num_fixed_parameters())); - return parsed_function()->RawParameterVariable(param_index); - } else { - return local_vars_.At(local_index); - } -} - -void BytecodeFlowGraphBuilder::StoreLocal(Operand local_index) { - if (is_generating_interpreter()) { - UNIMPLEMENTED(); // TODO(alexmarkov): interpreter - } else { - LocalVariable* local_var = LocalVariableAt(local_index.value()); - code_ += B->StoreLocalRaw(position_, local_var); - } -} - -void BytecodeFlowGraphBuilder::LoadLocal(Operand local_index) { - if (is_generating_interpreter()) { - UNIMPLEMENTED(); // TODO(alexmarkov): interpreter - } else { - LocalVariable* local_var = LocalVariableAt(local_index.value()); - code_ += B->LoadLocal(local_var); - } -} - -Value* BytecodeFlowGraphBuilder::Pop() { - LoadStackSlots(1); - return B->Pop(); -} - -intptr_t BytecodeFlowGraphBuilder::GetStackDepth() const { - ASSERT(!is_generating_interpreter()); - return B->GetStackDepth(); -} - -bool BytecodeFlowGraphBuilder::IsStackEmpty() const { - ASSERT(!is_generating_interpreter()); - return B->GetStackDepth() == 0; -} - -InferredTypeMetadata BytecodeFlowGraphBuilder::GetInferredType(intptr_t pc) { - ASSERT(!inferred_types_attribute_.IsNull()); - intptr_t i = inferred_types_index_; - const intptr_t len = inferred_types_attribute_.Length(); - for (; i < len; i += InferredTypeBytecodeAttribute::kNumElements) { - ASSERT(i + InferredTypeBytecodeAttribute::kNumElements <= len); - const intptr_t attr_pc = - InferredTypeBytecodeAttribute::GetPCAt(inferred_types_attribute_, i); - if (attr_pc == pc) { - const InferredTypeMetadata result = - InferredTypeBytecodeAttribute::GetInferredTypeAt( - Z, inferred_types_attribute_, i); - // Found. Next time, continue search at the next entry. - inferred_types_index_ = i + InferredTypeBytecodeAttribute::kNumElements; - return result; - } - if (attr_pc > pc) { - break; - } - } - // Not found. Next time, continue search at the last inspected entry. - inferred_types_index_ = i; - return InferredTypeMetadata(kDynamicCid, InferredTypeMetadata::kFlagNullable); -} - -void BytecodeFlowGraphBuilder::PropagateStackState(intptr_t target_pc) { - if (is_generating_interpreter() || IsStackEmpty()) { - return; - } - - Value* current_stack = B->stack_; - Value* target_stack = stack_states_.Lookup(target_pc); - - if (target_stack != nullptr) { - // Control flow join should observe the same stack state from - // all incoming branches. - RELEASE_ASSERT(target_stack == current_stack); - } else { - // Stack state propagation is supported for forward branches only. - RELEASE_ASSERT(target_pc > pc_); - stack_states_.Insert(target_pc, current_stack); - } -} - -// Drop values from the stack unless they are used in control flow joins -// which are not generated yet (dartbug.com/36374). -void BytecodeFlowGraphBuilder::DropUnusedValuesFromStack() { - intptr_t drop_depth = GetStackDepth(); - auto it = stack_states_.GetIterator(); - for (const auto* current = it.Next(); current != nullptr; - current = it.Next()) { - if (current->key > pc_) { - Value* used_value = current->value; - Value* value = B->stack_; - // Find if a value on the expression stack is used in a propagated - // stack state, and adjust [drop_depth] to preserve it. - for (intptr_t i = 0; i < drop_depth; ++i) { - if (value == used_value) { - drop_depth = i; - break; - } - value = value->next_use(); - } - } - } - for (intptr_t i = 0; i < drop_depth; ++i) { - B->Pop(); - } -} - -void BytecodeFlowGraphBuilder::BuildInstruction(KernelBytecode::Opcode opcode) { - switch (opcode) { -#define WIDE_CASE(name) case KernelBytecode::k##name##_Wide: -#define WIDE_CASE_0(name) -#define WIDE_CASE_A(name) -#define WIDE_CASE_D(name) WIDE_CASE(name) -#define WIDE_CASE_X(name) WIDE_CASE(name) -#define WIDE_CASE_T(name) WIDE_CASE(name) -#define WIDE_CASE_A_E(name) WIDE_CASE(name) -#define WIDE_CASE_A_Y(name) WIDE_CASE(name) -#define WIDE_CASE_D_F(name) WIDE_CASE(name) -#define WIDE_CASE_A_B_C(name) - -#define BUILD_BYTECODE_CASE(name, encoding, kind, op1, op2, op3) \ - BUILD_BYTECODE_CASE_##kind(name, encoding) - -#define BUILD_BYTECODE_CASE_WIDE(name, encoding) -#define BUILD_BYTECODE_CASE_RESV(name, encoding) -#define BUILD_BYTECODE_CASE_ORDN(name, encoding) \ - case KernelBytecode::k##name: \ - WIDE_CASE_##encoding(name) Build##name(); \ - break; - - PUBLIC_KERNEL_BYTECODES_LIST(BUILD_BYTECODE_CASE) - -#undef WIDE_CASE -#undef WIDE_CASE_0 -#undef WIDE_CASE_A -#undef WIDE_CASE_D -#undef WIDE_CASE_X -#undef WIDE_CASE_T -#undef WIDE_CASE_A_E -#undef WIDE_CASE_A_Y -#undef WIDE_CASE_D_F -#undef WIDE_CASE_A_B_C -#undef BUILD_BYTECODE_CASE -#undef BUILD_BYTECODE_CASE_WIDE -#undef BUILD_BYTECODE_CASE_RESV -#undef BUILD_BYTECODE_CASE_ORDN - - default: - FATAL1("Unsupported bytecode instruction %s\n", - KernelBytecode::NameOf(opcode)); - } -} - -void BytecodeFlowGraphBuilder::BuildEntry() { - AllocateLocalVariables(DecodeOperandD()); - AllocateFixedParameters(); -} - -void BytecodeFlowGraphBuilder::BuildEntryFixed() { - if (is_generating_interpreter()) { - UNIMPLEMENTED(); // TODO(alexmarkov): interpreter - } - - const intptr_t num_fixed_params = DecodeOperandA().value(); - ASSERT(num_fixed_params == function().num_fixed_parameters()); - - AllocateLocalVariables(DecodeOperandE()); - AllocateFixedParameters(); - - Fragment check_args; - - ASSERT(throw_no_such_method_ == nullptr); - throw_no_such_method_ = B->BuildThrowNoSuchMethod(); - - check_args += B->LoadArgDescriptor(); - check_args += - B->LoadNativeField(Slot::ArgumentsDescriptor_positional_count()); - check_args += B->IntConstant(num_fixed_params); - TargetEntryInstr *success1, *fail1; - check_args += B->BranchIfEqual(&success1, &fail1); - check_args = Fragment(check_args.entry, success1); - - check_args += B->LoadArgDescriptor(); - check_args += B->LoadNativeField(Slot::ArgumentsDescriptor_count()); - check_args += B->IntConstant(num_fixed_params); - TargetEntryInstr *success2, *fail2; - check_args += B->BranchIfEqual(&success2, &fail2); - check_args = Fragment(check_args.entry, success2); - - Fragment(fail1) + B->Goto(throw_no_such_method_); - Fragment(fail2) + B->Goto(throw_no_such_method_); - - ASSERT(IsStackEmpty()); - - if (!B->IsInlining() && !B->IsCompiledForOsr()) { - code_ += check_args; - } -} - -void BytecodeFlowGraphBuilder::BuildEntryOptional() { - if (is_generating_interpreter()) { - UNIMPLEMENTED(); // TODO(alexmarkov): interpreter - } - - const KBCInstr* next_instr = AllocateParametersAndLocalsForEntryOptional(); - - LocalVariable* temp_var = nullptr; - if (function().HasOptionalNamedParameters()) { - ASSERT(scratch_var_ != nullptr); - temp_var = scratch_var_; - } - - Fragment copy_args_prologue; - - // Code generated for EntryOptional is considered a prologue code. - // Prologue should span a range of block ids, so start a new block at the - // beginning and end a block at the end. - JoinEntryInstr* prologue_entry = B->BuildJoinEntry(); - copy_args_prologue += B->Goto(prologue_entry); - copy_args_prologue = Fragment(copy_args_prologue.entry, prologue_entry); - - ASSERT(throw_no_such_method_ == nullptr); - if (function().CanReceiveDynamicInvocation()) { - // We only pass a non-nullptr NSM block if argument shape checks are needed. - throw_no_such_method_ = B->BuildThrowNoSuchMethod(); - } - - PrologueBuilder prologue_builder(parsed_function(), B->last_used_block_id_, - B->IsCompiledForOsr(), B->IsInlining()); - - copy_args_prologue += prologue_builder.BuildOptionalParameterHandling( - throw_no_such_method_, temp_var); - - B->last_used_block_id_ = prologue_builder.last_used_block_id(); - - JoinEntryInstr* prologue_exit = B->BuildJoinEntry(); - copy_args_prologue += B->Goto(prologue_exit); - copy_args_prologue.current = prologue_exit; - - if (!B->IsInlining() && !B->IsCompiledForOsr()) { - code_ += copy_args_prologue; - } - - prologue_info_ = - PrologueInfo(prologue_entry->block_id(), prologue_exit->block_id() - 1); - - // Skip LoadConstant and Frame instructions. - next_pc_ = pc_ + (next_instr - bytecode_instr_); - - ASSERT(IsStackEmpty()); -} - -void BytecodeFlowGraphBuilder::BuildLoadConstant() { - if (is_generating_interpreter()) { - UNIMPLEMENTED(); // TODO(alexmarkov): interpreter - } - - // Handled in EntryOptional instruction. - UNREACHABLE(); -} - -void BytecodeFlowGraphBuilder::BuildFrame() { - if (is_generating_interpreter()) { - UNIMPLEMENTED(); // TODO(alexmarkov): interpreter - } - - // Handled in EntryOptional instruction. - UNREACHABLE(); -} - -void BytecodeFlowGraphBuilder::BuildCheckFunctionTypeArgs() { - if (is_generating_interpreter()) { - UNIMPLEMENTED(); // TODO(alexmarkov): interpreter - } - - const intptr_t expected_num_type_args = DecodeOperandA().value(); - LocalVariable* type_args_var = LocalVariableAt(DecodeOperandE().value()); - - const bool check_lengths = function().CanReceiveDynamicInvocation(); - - if (check_lengths && throw_no_such_method_ == nullptr) { - throw_no_such_method_ = B->BuildThrowNoSuchMethod(); - } - - Fragment setup_type_args; - - // Type args are always optional, so length can always be zero. - // If expect_type_args and lengths are being checked, a non-zero length must - // match the declaration length. - if (expected_num_type_args != 0) { - JoinEntryInstr* done = B->BuildJoinEntry(); - - TargetEntryInstr *then, *otherwise; - setup_type_args += B->LoadArgDescriptor(); - setup_type_args += - B->LoadNativeField(Slot::ArgumentsDescriptor_type_args_len()); - LocalVariable* len = B->MakeTemporary(); - setup_type_args += B->LoadLocal(len); - setup_type_args += B->IntConstant(0); - setup_type_args += B->BranchIfEqual(&then, &otherwise); - - JoinEntryInstr* join2 = B->BuildJoinEntry(); - - Fragment store_type_args(otherwise); - if (check_lengths) { - Fragment check_length; - check_length += B->LoadLocal(len); - check_length += B->IntConstant(expected_num_type_args); - TargetEntryInstr *then2, *fail; - check_length += B->BranchIfEqual(&then2, &fail); - check_length.current = then2; // Continue in the non-error case. - - Fragment(fail) + B->Goto(throw_no_such_method_); - - store_type_args += check_length; - } - - store_type_args += B->LoadArgDescriptor(); - store_type_args += B->LoadNativeField(Slot::ArgumentsDescriptor_count()); - store_type_args += B->LoadFpRelativeSlot( - compiler::target::kWordSize * - (1 + compiler::target::frame_layout.param_end_from_fp), - CompileType::CreateNullable(/*is_nullable=*/true, kTypeArgumentsCid)); - store_type_args += - B->StoreLocalRaw(TokenPosition::kNoSource, type_args_var); - store_type_args += B->Drop(); - store_type_args += B->Goto(join2); - - Fragment null_type_args(then); - null_type_args += B->NullConstant(); - null_type_args += B->StoreLocalRaw(TokenPosition::kNoSource, type_args_var); - null_type_args += B->Drop(); - null_type_args += B->Goto(join2); - - Fragment(join2) + B->Drop() + B->Goto(done); - - setup_type_args.current = done; - } else if (check_lengths) { - TargetEntryInstr *then, *fail; - setup_type_args += B->LoadArgDescriptor(); - setup_type_args += - B->LoadNativeField(Slot::ArgumentsDescriptor_type_args_len()); - setup_type_args += B->IntConstant(0); - setup_type_args += B->BranchIfEqual(&then, &fail); - setup_type_args.current = then; // Continue in the non-error case. - - Fragment(fail) + B->Goto(throw_no_such_method_); - } - - ASSERT(IsStackEmpty()); - - if (expected_num_type_args != 0) { - parsed_function()->set_function_type_arguments(type_args_var); - parsed_function()->SetRawTypeArgumentsVariable(type_args_var); - } - - if (!B->IsInlining() && !B->IsCompiledForOsr()) { - code_ += setup_type_args; - } -} - -void BytecodeFlowGraphBuilder::BuildCheckStack() { - if (is_generating_interpreter()) { - UNIMPLEMENTED(); // TODO(alexmarkov): interpreter - } - const intptr_t loop_depth = DecodeOperandA().value(); - if (loop_depth == 0) { - ASSERT(IsStackEmpty()); - code_ += B->CheckStackOverflowInPrologue(position_); - } else { - const intptr_t stack_depth = B->GetStackDepth(); - code_ += B->CheckStackOverflow(position_, stack_depth, loop_depth); - } -} - -void BytecodeFlowGraphBuilder::BuildDebugCheck() { - if (is_generating_interpreter()) { - UNIMPLEMENTED(); // TODO(alexmarkov): interpreter - } - // DebugStepCheck instructions are emitted for all explicit DebugCheck - // opcodes as well as for implicit DEBUG_CHECK executed by the interpreter - // for some opcodes, but not before the first explicit DebugCheck opcode is - // encountered. - build_debug_step_checks_ = true; - BuildDebugStepCheck(); -} - -void BytecodeFlowGraphBuilder::BuildPushConstant() { - PushConstant(ConstantAt(DecodeOperandD())); -} - -void BytecodeFlowGraphBuilder::BuildPushNull() { - code_ += B->NullConstant(); -} - -void BytecodeFlowGraphBuilder::BuildPushTrue() { - code_ += B->Constant(Bool::True()); -} - -void BytecodeFlowGraphBuilder::BuildPushFalse() { - code_ += B->Constant(Bool::False()); -} - -void BytecodeFlowGraphBuilder::BuildPushInt() { - if (is_generating_interpreter()) { - UNIMPLEMENTED(); // TODO(alexmarkov): interpreter - } - code_ += B->IntConstant(DecodeOperandX().value()); -} - -void BytecodeFlowGraphBuilder::BuildStoreLocal() { - LoadStackSlots(1); - const Operand local_index = DecodeOperandX(); - StoreLocal(local_index); -} - -void BytecodeFlowGraphBuilder::BuildPopLocal() { - BuildStoreLocal(); - code_ += B->Drop(); -} - -void BytecodeFlowGraphBuilder::BuildPush() { - const Operand local_index = DecodeOperandX(); - LoadLocal(local_index); -} - -void BytecodeFlowGraphBuilder::BuildDirectCallCommon(bool is_unchecked_call) { - if (is_generating_interpreter()) { - UNIMPLEMENTED(); // TODO(alexmarkov): interpreter - } - - // A DebugStepCheck is performed as part of the calling stub. - - const Function& target = Function::Cast(ConstantAt(DecodeOperandD()).value()); - const intptr_t argc = DecodeOperandF().value(); - - switch (target.recognized_kind()) { - case MethodRecognizer::kFfiAsFunctionInternal: - BuildFfiAsFunction(); - return; - case MethodRecognizer::kFfiNativeCallbackFunction: - if (CompilerState::Current().is_aot()) { - BuildFfiNativeCallbackFunction(); - return; - } - break; - case MethodRecognizer::kObjectIdentical: - // Note: similar optimization is performed in AST flow graph builder - - // see StreamingFlowGraphBuilder::BuildStaticInvocation, - // special_case_identical. - // TODO(alexmarkov): find a better place for this optimization. - ASSERT(argc == 2); - code_ += B->StrictCompare(Token::kEQ_STRICT, /*number_check=*/true); - return; - case MethodRecognizer::kAsyncStackTraceHelper: - case MethodRecognizer::kSetAsyncThreadStackTrace: - if (!FLAG_causal_async_stacks) { - ASSERT(argc == 1); - // Drop the ignored parameter to _asyncStackTraceHelper(:async_op) or - // _setAsyncThreadStackTrace(stackTrace). - code_ += B->Drop(); - code_ += B->NullConstant(); - return; - } - break; - case MethodRecognizer::kClearAsyncThreadStackTrace: - if (!FLAG_causal_async_stacks) { - ASSERT(argc == 0); - code_ += B->NullConstant(); - return; - } - break; - case MethodRecognizer::kStringBaseInterpolate: - ASSERT(argc == 1); - code_ += B->StringInterpolate(position_); - return; - default: - break; - } - - const Array& arg_desc_array = - Array::Cast(ConstantAt(DecodeOperandD(), 1).value()); - const ArgumentsDescriptor arg_desc(arg_desc_array); - - InputsArray* arguments = B->GetArguments(argc); - - StaticCallInstr* call = new (Z) StaticCallInstr( - position_, target, arg_desc.TypeArgsLen(), - Array::ZoneHandle(Z, arg_desc.GetArgumentNames()), arguments, - *ic_data_array_, B->GetNextDeoptId(), - target.IsDynamicFunction() ? ICData::kSuper : ICData::kStatic); - - if (is_unchecked_call) { - call->set_entry_kind(Code::EntryKind::kUnchecked); - } - - if (!call->InitResultType(Z)) { - if (!inferred_types_attribute_.IsNull()) { - const InferredTypeMetadata result_type = GetInferredType(pc_); - if (!result_type.IsTrivial()) { - call->SetResultType(Z, result_type.ToCompileType(Z)); - } - } - } - - code_ <<= call; - B->Push(call); -} - -void BytecodeFlowGraphBuilder::BuildDirectCall() { - BuildDirectCallCommon(/* is_unchecked_call = */ false); -} - -void BytecodeFlowGraphBuilder::BuildUncheckedDirectCall() { - BuildDirectCallCommon(/* is_unchecked_call = */ true); -} - -static void ComputeTokenKindAndCheckedArguments( - const String& name, - const ArgumentsDescriptor& arg_desc, - Token::Kind* token_kind, - intptr_t* checked_argument_count) { - *token_kind = MethodTokenRecognizer::RecognizeTokenKind(name); - - *checked_argument_count = 1; - if (*token_kind != Token::kILLEGAL) { - intptr_t argument_count = arg_desc.Count(); - ASSERT(argument_count <= 2); - *checked_argument_count = (*token_kind == Token::kSET) ? 1 : argument_count; - } else if (Library::IsPrivateCoreLibName(name, - Symbols::_simpleInstanceOf())) { - ASSERT(arg_desc.Count() == 2); - *checked_argument_count = 2; - *token_kind = Token::kIS; - } else if (Library::IsPrivateCoreLibName(name, Symbols::_instanceOf())) { - ASSERT(arg_desc.Count() == 4); - *token_kind = Token::kIS; - } -} - -void BytecodeFlowGraphBuilder::BuildInterfaceCallCommon( - bool is_unchecked_call, - bool is_instantiated_call) { - if (is_generating_interpreter()) { - UNIMPLEMENTED(); // TODO(alexmarkov): interpreter - } - - // A DebugStepCheck is performed as part of the calling stub. - - const Function& interface_target = - Function::Cast(ConstantAt(DecodeOperandD()).value()); - const String& name = String::ZoneHandle(Z, interface_target.name()); - ASSERT(name.IsSymbol()); - - const Array& arg_desc_array = - Array::Cast(ConstantAt(DecodeOperandD(), 1).value()); - const ArgumentsDescriptor arg_desc(arg_desc_array); - - Token::Kind token_kind; - intptr_t checked_argument_count; - ComputeTokenKindAndCheckedArguments(name, arg_desc, &token_kind, - &checked_argument_count); - - const intptr_t argc = DecodeOperandF().value(); - InputsArray* arguments = B->GetArguments(argc); - - InstanceCallInstr* call = new (Z) InstanceCallInstr( - position_, name, token_kind, arguments, arg_desc.TypeArgsLen(), - Array::ZoneHandle(Z, arg_desc.GetArgumentNames()), checked_argument_count, - *ic_data_array_, B->GetNextDeoptId(), interface_target); - - if (!inferred_types_attribute_.IsNull()) { - const InferredTypeMetadata result_type = GetInferredType(pc_); - if (!result_type.IsTrivial()) { - call->SetResultType(Z, result_type.ToCompileType(Z)); - } - } - - if (is_unchecked_call) { - call->set_entry_kind(Code::EntryKind::kUnchecked); - } - - if (is_instantiated_call) { - const AbstractType& static_receiver_type = - AbstractType::Cast(ConstantAt(DecodeOperandD(), 2).value()); - call->set_receivers_static_type(&static_receiver_type); - } else { - const Class& owner = Class::Handle(Z, interface_target.Owner()); - const AbstractType& type = - AbstractType::ZoneHandle(Z, owner.DeclarationType()); - call->set_receivers_static_type(&type); - } - - code_ <<= call; - B->Push(call); -} - -void BytecodeFlowGraphBuilder::BuildInterfaceCall() { - BuildInterfaceCallCommon(/*is_unchecked_call=*/false, - /*is_instantiated_call=*/false); -} - -void BytecodeFlowGraphBuilder::BuildInstantiatedInterfaceCall() { - BuildInterfaceCallCommon(/*is_unchecked_call=*/false, - /*is_instantiated_call=*/true); -} - -void BytecodeFlowGraphBuilder::BuildUncheckedInterfaceCall() { - BuildInterfaceCallCommon(/*is_unchecked_call=*/true, - /*is_instantiated_call=*/false); -} - -void BytecodeFlowGraphBuilder::BuildUncheckedClosureCall() { - if (is_generating_interpreter()) { - UNIMPLEMENTED(); // TODO(alexmarkov): interpreter - } - - BuildDebugStepCheck(); - - const Array& arg_desc_array = - Array::Cast(ConstantAt(DecodeOperandD()).value()); - const ArgumentsDescriptor arg_desc(arg_desc_array); - - const intptr_t argc = DecodeOperandF().value(); - - LocalVariable* receiver_temp = B->MakeTemporary(); - code_ += B->CheckNull(position_, receiver_temp, Symbols::Call(), - /*clear_temp=*/false); - - code_ += B->LoadNativeField(Slot::Closure_function()); - - InputsArray* arguments = B->GetArguments(argc + 1); - - ClosureCallInstr* call = new (Z) ClosureCallInstr( - arguments, arg_desc.TypeArgsLen(), - Array::ZoneHandle(Z, arg_desc.GetArgumentNames()), position_, - B->GetNextDeoptId(), Code::EntryKind::kUnchecked); - - // TODO(alexmarkov): use inferred result type for ClosureCallInstr - // if (!inferred_types_attribute_.IsNull()) { - // const InferredTypeMetadata result_type = GetInferredType(pc_); - // if (!result_type.IsTrivial()) { - // call->SetResultType(Z, result_type.ToCompileType(Z)); - // } - // } - - code_ <<= call; - B->Push(call); -} - -void BytecodeFlowGraphBuilder::BuildDynamicCall() { - if (is_generating_interpreter()) { - UNIMPLEMENTED(); // TODO(alexmarkov): interpreter - } - - // A DebugStepCheck is performed as part of the calling stub. - - const String& name = String::Cast(ConstantAt(DecodeOperandD()).value()); - const ArgumentsDescriptor arg_desc( - Array::Cast(ConstantAt(DecodeOperandD(), 1).value())); - - Token::Kind token_kind; - intptr_t checked_argument_count; - ComputeTokenKindAndCheckedArguments(name, arg_desc, &token_kind, - &checked_argument_count); - - const intptr_t argc = DecodeOperandF().value(); - InputsArray* arguments = B->GetArguments(argc); - - const Function& interface_target = Function::null_function(); - - InstanceCallInstr* call = new (Z) InstanceCallInstr( - position_, name, token_kind, arguments, arg_desc.TypeArgsLen(), - Array::ZoneHandle(Z, arg_desc.GetArgumentNames()), checked_argument_count, - *ic_data_array_, B->GetNextDeoptId(), interface_target); - - if (!inferred_types_attribute_.IsNull()) { - const InferredTypeMetadata result_type = GetInferredType(pc_); - if (!result_type.IsTrivial()) { - call->SetResultType(Z, result_type.ToCompileType(Z)); - } - } - - code_ <<= call; - B->Push(call); -} - -void BytecodeFlowGraphBuilder::BuildNativeCall() { - if (is_generating_interpreter()) { - UNIMPLEMENTED(); // TODO(alexmarkov): interpreter - } - - ASSERT(function().is_native()); - B->InlineBailout("BytecodeFlowGraphBuilder::BuildNativeCall"); - - const auto& name = String::ZoneHandle(Z, function().native_name()); - const intptr_t num_args = - function().NumParameters() + (function().IsGeneric() ? 1 : 0); - InputsArray* arguments = B->GetArguments(num_args); - auto* call = - new (Z) NativeCallInstr(&name, &function(), FLAG_link_natives_lazily, - function().end_token_pos(), arguments); - code_ <<= call; - B->Push(call); -} - -void BytecodeFlowGraphBuilder::BuildAllocate() { - if (is_generating_interpreter()) { - UNIMPLEMENTED(); // TODO(alexmarkov): interpreter - } - - const Class& klass = Class::Cast(ConstantAt(DecodeOperandD()).value()); - - AllocateObjectInstr* allocate = new (Z) AllocateObjectInstr(position_, klass); - - code_ <<= allocate; - B->Push(allocate); -} - -void BytecodeFlowGraphBuilder::BuildAllocateT() { - if (is_generating_interpreter()) { - UNIMPLEMENTED(); // TODO(alexmarkov): interpreter - } - - const Class& klass = Class::Cast(PopConstant().value()); - Value* type_arguments = Pop(); - - AllocateObjectInstr* allocate = - new (Z) AllocateObjectInstr(position_, klass, type_arguments); - - code_ <<= allocate; - B->Push(allocate); -} - -void BytecodeFlowGraphBuilder::BuildAllocateContext() { - if (is_generating_interpreter()) { - UNIMPLEMENTED(); // TODO(alexmarkov): interpreter - } - - const intptr_t context_id = DecodeOperandA().value(); - const intptr_t num_context_vars = DecodeOperandE().value(); - - auto& context_slots = CompilerState::Current().GetDummyContextSlots( - context_id, num_context_vars); - code_ += B->AllocateContext(context_slots); -} - -void BytecodeFlowGraphBuilder::BuildCloneContext() { - if (is_generating_interpreter()) { - UNIMPLEMENTED(); // TODO(alexmarkov): interpreter - } - - LoadStackSlots(1); - const intptr_t context_id = DecodeOperandA().value(); - const intptr_t num_context_vars = DecodeOperandE().value(); - - auto& context_slots = CompilerState::Current().GetDummyContextSlots( - context_id, num_context_vars); - CloneContextInstr* clone_instruction = new (Z) CloneContextInstr( - TokenPosition::kNoSource, Pop(), context_slots, B->GetNextDeoptId()); - code_ <<= clone_instruction; - B->Push(clone_instruction); -} - -void BytecodeFlowGraphBuilder::BuildCreateArrayTOS() { - LoadStackSlots(2); - code_ += B->CreateArray(); -} - -const Slot& ClosureSlotByField(const Field& field) { - const intptr_t offset = field.HostOffset(); - if (offset == Closure::instantiator_type_arguments_offset()) { - return Slot::Closure_instantiator_type_arguments(); - } else if (offset == Closure::function_type_arguments_offset()) { - return Slot::Closure_function_type_arguments(); - } else if (offset == Closure::delayed_type_arguments_offset()) { - return Slot::Closure_delayed_type_arguments(); - } else if (offset == Closure::function_offset()) { - return Slot::Closure_function(); - } else if (offset == Closure::context_offset()) { - return Slot::Closure_context(); - } else { - RELEASE_ASSERT(offset == Closure::hash_offset()); - return Slot::Closure_hash(); - } -} - -void BytecodeFlowGraphBuilder::BuildStoreFieldTOS() { - if (is_generating_interpreter()) { - UNIMPLEMENTED(); // TODO(alexmarkov): interpreter - } - - LoadStackSlots(2); - Operand cp_index = DecodeOperandD(); - - const Field& field = Field::Cast(ConstantAt(cp_index, 1).value()); - ASSERT(Smi::Cast(ConstantAt(cp_index).value()).Value() * kWordSize == - field.HostOffset()); - - if (field.Owner() == isolate()->object_store()->closure_class()) { - // Stores to _Closure fields are lower-level. - code_ += - B->StoreInstanceField(position_, ClosureSlotByField(field), - StoreInstanceFieldInstr::Kind::kInitializing); - } else { - // The rest of the StoreFieldTOS are for field initializers. - // TODO(alexmarkov): Consider adding a flag to StoreFieldTOS or even - // adding a separate bytecode instruction. - code_ += B->StoreInstanceFieldGuarded( - field, StoreInstanceFieldInstr::Kind::kInitializing); - } -} - -void BytecodeFlowGraphBuilder::BuildLoadFieldTOS() { - if (is_generating_interpreter()) { - UNIMPLEMENTED(); // TODO(alexmarkov): interpreter - } - - LoadStackSlots(1); - Operand cp_index = DecodeOperandD(); - - const Field& field = Field::Cast(ConstantAt(cp_index, 1).value()); - ASSERT(Smi::Cast(ConstantAt(cp_index).value()).Value() * kWordSize == - field.HostOffset()); - - if (field.Owner() == isolate()->object_store()->closure_class()) { - // Loads from _Closure fields are lower-level. - code_ += B->LoadNativeField(ClosureSlotByField(field)); - } else { - code_ += B->LoadField(field, /*calls_initializer=*/false); - } -} - -void BytecodeFlowGraphBuilder::BuildStoreContextParent() { - LoadStackSlots(2); - - code_ += B->StoreInstanceField(position_, Slot::Context_parent(), - StoreInstanceFieldInstr::Kind::kInitializing); -} - -void BytecodeFlowGraphBuilder::BuildLoadContextParent() { - LoadStackSlots(1); - - code_ += B->LoadNativeField(Slot::Context_parent()); -} - -void BytecodeFlowGraphBuilder::BuildStoreContextVar() { - if (is_generating_interpreter()) { - UNIMPLEMENTED(); // TODO(alexmarkov): interpreter - } - - LoadStackSlots(2); - const intptr_t context_id = DecodeOperandA().value(); - const intptr_t var_index = DecodeOperandE().value(); - - auto var = - CompilerState::Current().GetDummyCapturedVariable(context_id, var_index); - code_ += B->StoreInstanceField( - position_, Slot::GetContextVariableSlotFor(thread(), *var)); -} - -void BytecodeFlowGraphBuilder::BuildLoadContextVar() { - if (is_generating_interpreter()) { - UNIMPLEMENTED(); // TODO(alexmarkov): interpreter - } - - LoadStackSlots(1); - const intptr_t context_id = DecodeOperandA().value(); - const intptr_t var_index = DecodeOperandE().value(); - - auto var = - CompilerState::Current().GetDummyCapturedVariable(context_id, var_index); - code_ += B->LoadNativeField(Slot::GetContextVariableSlotFor(thread(), *var)); -} - -void BytecodeFlowGraphBuilder::BuildLoadTypeArgumentsField() { - if (is_generating_interpreter()) { - UNIMPLEMENTED(); // TODO(alexmarkov): interpreter - } - - LoadStackSlots(1); - const intptr_t offset = - Smi::Cast(ConstantAt(DecodeOperandD()).value()).Value() * - compiler::target::kWordSize; - - code_ += B->LoadNativeField(Slot::GetTypeArgumentsSlotAt(thread(), offset)); -} - -void BytecodeFlowGraphBuilder::BuildStoreStaticTOS() { - if (is_generating_interpreter()) { - UNIMPLEMENTED(); // TODO(alexmarkov): interpreter - } - - LoadStackSlots(1); - Operand cp_index = DecodeOperandD(); - - const Field& field = Field::Cast(ConstantAt(cp_index).value()); - - code_ += B->StoreStaticField(position_, field); -} - -void BytecodeFlowGraphBuilder::BuildInitLateField() { - if (is_generating_interpreter()) { - UNIMPLEMENTED(); // TODO(alexmarkov): interpreter - } - - LoadStackSlots(1); - Operand cp_index = DecodeOperandD(); - - const Field& field = Field::Cast(ConstantAt(cp_index, 1).value()); - ASSERT(Smi::Cast(ConstantAt(cp_index).value()).Value() * kWordSize == - field.HostOffset()); - - code_ += B->Constant(Object::sentinel()); - code_ += B->StoreInstanceField( - field, StoreInstanceFieldInstr::Kind::kInitializing, kNoStoreBarrier); -} - -void BytecodeFlowGraphBuilder::BuildPushUninitializedSentinel() { - code_ += B->Constant(Object::sentinel()); -} - -void BytecodeFlowGraphBuilder::BuildJumpIfInitialized() { - code_ += B->Constant(Object::sentinel()); - BuildJumpIfStrictCompare(Token::kNE); -} - -void BytecodeFlowGraphBuilder::BuildLoadStatic() { - const Constant operand = ConstantAt(DecodeOperandD()); - const auto& field = Field::Cast(operand.value()); - // All constant expressions (including access to const fields) are evaluated - // in bytecode. However, values of injected cid fields are only available in - // the VM. In such case, evaluate const fields with known value here. - if (field.is_const() && !field.has_nontrivial_initializer()) { - const auto& value = Object::ZoneHandle(Z, field.StaticValue()); - ASSERT((value.raw() != Object::sentinel().raw()) && - (value.raw() != Object::transition_sentinel().raw())); - code_ += B->Constant(value); - return; - } - code_ += B->LoadStaticField(field, /*calls_initializer=*/false); -} - -void BytecodeFlowGraphBuilder::BuildStoreIndexedTOS() { - LoadStackSlots(3); - code_ += B->StoreIndexed(kArrayCid); -} - -void BytecodeFlowGraphBuilder::BuildBooleanNegateTOS() { - LoadStackSlots(1); - code_ += B->BooleanNegate(); -} - -void BytecodeFlowGraphBuilder::BuildInstantiateType() { - if (is_generating_interpreter()) { - UNIMPLEMENTED(); // TODO(alexmarkov): interpreter - } - - const AbstractType& type = - AbstractType::Cast(ConstantAt(DecodeOperandD()).value()); - - LoadStackSlots(2); - code_ += B->InstantiateType(type); -} - -void BytecodeFlowGraphBuilder::BuildInstantiateTypeArgumentsTOS() { - if (is_generating_interpreter()) { - UNIMPLEMENTED(); // TODO(alexmarkov): interpreter - } - - const TypeArguments& type_args = - TypeArguments::Cast(ConstantAt(DecodeOperandE()).value()); - - LoadStackSlots(2); - code_ += B->InstantiateTypeArguments(type_args); -} - -void BytecodeFlowGraphBuilder::BuildAssertBoolean() { - LoadStackSlots(1); - code_ += B->AssertBool(position_); -} - -void BytecodeFlowGraphBuilder::BuildAssertAssignable() { - if (is_generating_interpreter()) { - UNIMPLEMENTED(); // TODO(alexmarkov): interpreter - } - - LoadStackSlots(5); - - const AbstractType& dst_type = - AbstractType::Cast(B->Peek(/*depth=*/3)->AsConstant()->value()); - if (dst_type.IsTopTypeForSubtyping()) { - code_ += B->Drop(); // dst_name - code_ += B->Drop(); // function_type_args - code_ += B->Drop(); // instantiator_type_args - code_ += B->Drop(); // dst_type - // Leave value on top. - return; - } - - const String& dst_name = String::Cast(PopConstant().value()); - Value* function_type_args = Pop(); - Value* instantiator_type_args = Pop(); - Value* dst_type_value = Pop(); - Value* value = Pop(); - - AssertAssignableInstr* instr = new (Z) AssertAssignableInstr( - position_, value, dst_type_value, instantiator_type_args, - function_type_args, dst_name, B->GetNextDeoptId()); - - code_ <<= instr; - - B->Push(instr); -} - -void BytecodeFlowGraphBuilder::BuildAssertSubtype() { - if (is_generating_interpreter()) { - UNIMPLEMENTED(); // TODO(alexmarkov): interpreter - } - - LoadStackSlots(5); - - Value* dst_name = Pop(); - Value* super_type = Pop(); - Value* sub_type = Pop(); - Value* function_type_args = Pop(); - Value* instantiator_type_args = Pop(); - - AssertSubtypeInstr* instr = new (Z) - AssertSubtypeInstr(position_, instantiator_type_args, function_type_args, - sub_type, super_type, dst_name, B->GetNextDeoptId()); - code_ <<= instr; -} - -void BytecodeFlowGraphBuilder::BuildNullCheck() { - if (is_generating_interpreter()) { - UNIMPLEMENTED(); // TODO(alexmarkov): interpreter - } - - const String& selector = - String::CheckedZoneHandle(Z, ConstantAt(DecodeOperandD()).value().raw()); - - LocalVariable* receiver_temp = B->MakeTemporary(); - code_ += - B->CheckNull(position_, receiver_temp, selector, /*clear_temp=*/false); - code_ += B->Drop(); -} - -void BytecodeFlowGraphBuilder::BuildJump() { - if (is_generating_interpreter()) { - UNIMPLEMENTED(); // TODO(alexmarkov): interpreter - } - - const intptr_t target_pc = pc_ + DecodeOperandT().value(); - JoinEntryInstr* join = jump_targets_.Lookup(target_pc); - ASSERT(join != nullptr); - code_ += B->Goto(join); - PropagateStackState(target_pc); - B->stack_ = nullptr; -} - -void BytecodeFlowGraphBuilder::BuildJumpIfNoAsserts() { - ASSERT(IsStackEmpty()); - if (!isolate()->asserts()) { - BuildJump(); - // Skip all instructions up to the target PC, as they are all unreachable. - // If not skipped, some of the assert code may be considered reachable - // (if it contains jumps) and generated. The problem is that generated - // code may expect values left on the stack from unreachable - // (and not generated) code which immediately follows this Jump. - next_pc_ = pc_ + DecodeOperandT().value(); - ASSERT(next_pc_ > pc_); - } -} - -void BytecodeFlowGraphBuilder::BuildJumpIfNotZeroTypeArgs() { - if (is_generating_interpreter()) { - UNIMPLEMENTED(); // TODO(alexmarkov): interpreter - } - - TargetEntryInstr *is_zero, *is_not_zero; - code_ += B->LoadArgDescriptor(); - code_ += B->LoadNativeField(Slot::ArgumentsDescriptor_type_args_len()); - code_ += B->IntConstant(0); - code_ += B->BranchIfEqual(&is_zero, &is_not_zero); - - const intptr_t target_pc = pc_ + DecodeOperandT().value(); - JoinEntryInstr* join = jump_targets_.Lookup(target_pc); - ASSERT(join != nullptr); - Fragment(is_not_zero) += B->Goto(join); - PropagateStackState(target_pc); - - code_ = Fragment(code_.entry, is_zero); -} - -void BytecodeFlowGraphBuilder::BuildJumpIfStrictCompare(Token::Kind cmp_kind) { - ASSERT((cmp_kind == Token::kEQ) || (cmp_kind == Token::kNE)); - - if (is_generating_interpreter()) { - UNIMPLEMENTED(); // TODO(alexmarkov): interpreter - } - - LoadStackSlots(2); - - // Fallthrough should correspond to 'then' branch target. - // This results in a slightly better regalloc. - TargetEntryInstr* then_entry = nullptr; - TargetEntryInstr* else_entry = nullptr; - code_ += B->BranchIfEqual(&then_entry, &else_entry, - /* negate = */ (cmp_kind == Token::kEQ)); - - const intptr_t target_pc = pc_ + DecodeOperandT().value(); - JoinEntryInstr* join = jump_targets_.Lookup(target_pc); - ASSERT(join != nullptr); - - code_ = Fragment(else_entry); - code_ += B->Goto(join); - PropagateStackState(target_pc); - - code_ = Fragment(then_entry); -} - -void BytecodeFlowGraphBuilder::BuildJumpIfEqStrict() { - BuildJumpIfStrictCompare(Token::kEQ); -} - -void BytecodeFlowGraphBuilder::BuildJumpIfNeStrict() { - BuildJumpIfStrictCompare(Token::kNE); -} - -void BytecodeFlowGraphBuilder::BuildJumpIfTrue() { - code_ += B->Constant(Bool::True()); - BuildJumpIfStrictCompare(Token::kEQ); -} - -void BytecodeFlowGraphBuilder::BuildJumpIfFalse() { - code_ += B->Constant(Bool::False()); - BuildJumpIfStrictCompare(Token::kEQ); -} - -void BytecodeFlowGraphBuilder::BuildJumpIfNull() { - code_ += B->NullConstant(); - BuildJumpIfStrictCompare(Token::kEQ); -} - -void BytecodeFlowGraphBuilder::BuildJumpIfNotNull() { - code_ += B->NullConstant(); - BuildJumpIfStrictCompare(Token::kNE); -} - -void BytecodeFlowGraphBuilder::BuildJumpIfUnchecked() { - if (is_generating_interpreter()) { - UNIMPLEMENTED(); // TODO(alexmarkov): interpreter - } - - ASSERT(IsStackEmpty()); - - const intptr_t target_pc = pc_ + DecodeOperandT().value(); - JoinEntryInstr* target = jump_targets_.Lookup(target_pc); - ASSERT(target != nullptr); - FunctionEntryInstr* unchecked_entry = nullptr; - const intptr_t kCheckedEntry = - static_cast(UncheckedEntryPointStyle::kNone); - const intptr_t kUncheckedEntry = - static_cast(UncheckedEntryPointStyle::kSharedWithVariable); - - switch (entry_point_style_) { - case UncheckedEntryPointStyle::kNone: { - JoinEntryInstr* do_checks = B->BuildJoinEntry(); - code_ += B->Goto(B->InliningUncheckedEntry() ? target : do_checks); - code_ = Fragment(do_checks); - } break; - - case UncheckedEntryPointStyle::kSeparate: { - // Route normal entry to checks. - if (FLAG_enable_testing_pragmas) { - code_ += B->IntConstant(kCheckedEntry); - code_ += B->BuildEntryPointsIntrospection(); - } - Fragment do_checks = code_; - - // Create a separate unchecked entry point. - unchecked_entry = B->BuildFunctionEntry(graph_entry_); - code_ = Fragment(unchecked_entry); - - // Re-build prologue for unchecked entry point. It can only contain - // Entry, CheckStack and DebugCheck instructions. - bytecode_instr_ = raw_bytecode_; - ASSERT(KernelBytecode::IsEntryOpcode(bytecode_instr_)); - bytecode_instr_ = KernelBytecode::Next(bytecode_instr_); - while (!KernelBytecode::IsJumpIfUncheckedOpcode(bytecode_instr_)) { - ASSERT(KernelBytecode::IsCheckStackOpcode(bytecode_instr_) || - KernelBytecode::IsDebugCheckOpcode(bytecode_instr_)); - ASSERT(jump_targets_.Lookup(bytecode_instr_ - raw_bytecode_) == - nullptr); - BuildInstruction(KernelBytecode::DecodeOpcode(bytecode_instr_)); - bytecode_instr_ = KernelBytecode::Next(bytecode_instr_); - } - ASSERT((bytecode_instr_ - raw_bytecode_) == pc_); - - if (FLAG_enable_testing_pragmas) { - code_ += B->IntConstant( - static_cast(UncheckedEntryPointStyle::kSeparate)); - code_ += B->BuildEntryPointsIntrospection(); - } - code_ += B->Goto(target); - - code_ = do_checks; - } break; - - case UncheckedEntryPointStyle::kSharedWithVariable: { - LocalVariable* ep_var = parsed_function()->entry_points_temp_var(); - - // Dispatch based on the value of entry_points_temp_var. - TargetEntryInstr *do_checks, *skip_checks; - if (FLAG_enable_testing_pragmas) { - code_ += B->LoadLocal(ep_var); - code_ += B->BuildEntryPointsIntrospection(); - } - code_ += B->LoadLocal(ep_var); - code_ += B->IntConstant(kUncheckedEntry); - code_ += B->BranchIfEqual(&skip_checks, &do_checks, /*negate=*/false); - - code_ = Fragment(skip_checks); - code_ += B->Goto(target); - - // Relink the body of the function from normal entry to 'prologue_join'. - JoinEntryInstr* prologue_join = B->BuildJoinEntry(); - FunctionEntryInstr* normal_entry = graph_entry_->normal_entry(); - if (normal_entry->next() != nullptr) { - prologue_join->LinkTo(normal_entry->next()); - normal_entry->set_next(nullptr); - } - - unchecked_entry = B->BuildFunctionEntry(graph_entry_); - code_ = Fragment(unchecked_entry); - code_ += B->IntConstant(kUncheckedEntry); - code_ += B->StoreLocal(TokenPosition::kNoSource, ep_var); - code_ += B->Drop(); - code_ += B->Goto(prologue_join); - - code_ = Fragment(normal_entry); - code_ += B->IntConstant(kCheckedEntry); - code_ += B->StoreLocal(TokenPosition::kNoSource, ep_var); - code_ += B->Drop(); - code_ += B->Goto(prologue_join); - - code_ = Fragment(do_checks); - } break; - } - - if (unchecked_entry != nullptr) { - B->RecordUncheckedEntryPoint(graph_entry_, unchecked_entry); - } -} - -void BytecodeFlowGraphBuilder::BuildDrop1() { - if (is_generating_interpreter()) { - UNIMPLEMENTED(); // TODO(alexmarkov): interpreter - // AdjustSP(-1); - } else { - code_ += B->Drop(); - } -} - -void BytecodeFlowGraphBuilder::BuildReturnTOS() { - BuildDebugStepCheck(); - LoadStackSlots(1); - ASSERT(code_.is_open()); - intptr_t yield_index = PcDescriptorsLayout::kInvalidYieldIndex; - if (function().IsAsyncClosure() || function().IsAsyncGenClosure()) { - if (pc_ == last_yield_point_pc_) { - // The return might actually be a yield point, if so we need to attach the - // yield index to the return instruction. - yield_index = last_yield_point_index_; - } - } - code_ += B->Return(position_, yield_index); - ASSERT(IsStackEmpty()); -} - -void BytecodeFlowGraphBuilder::BuildTrap() { - code_ += Fragment(new (Z) StopInstr("Bytecode Trap instruction")).closed(); -} - -void BytecodeFlowGraphBuilder::BuildThrow() { - if (is_generating_interpreter()) { - UNIMPLEMENTED(); // TODO(alexmarkov): interpreter - } - - if (DecodeOperandA().value() == 0) { - // throw - LoadStackSlots(1); - Value* exception = Pop(); - code_ += - Fragment(new (Z) ThrowInstr(position_, B->GetNextDeoptId(), exception)) - .closed(); - } else { - // rethrow - LoadStackSlots(2); - Value* stacktrace = Pop(); - Value* exception = Pop(); - code_ += Fragment(new (Z) ReThrowInstr(position_, kInvalidTryIndex, - B->GetNextDeoptId(), exception, - stacktrace)) - .closed(); - } - - ASSERT(code_.is_closed()); - - if (!IsStackEmpty()) { - DropUnusedValuesFromStack(); - B->stack_ = nullptr; - } -} - -void BytecodeFlowGraphBuilder::BuildMoveSpecial() { - if (is_generating_interpreter()) { - UNIMPLEMENTED(); // TODO(alexmarkov): interpreter - } - - LocalVariable* special_var = nullptr; - switch (DecodeOperandA().value()) { - case KernelBytecode::kExceptionSpecialIndex: - ASSERT(exception_var_ != nullptr); - special_var = exception_var_; - break; - case KernelBytecode::kStackTraceSpecialIndex: - ASSERT(stacktrace_var_ != nullptr); - special_var = stacktrace_var_; - break; - default: - UNREACHABLE(); - } - - code_ += B->LoadLocal(special_var); - StoreLocal(DecodeOperandY()); - code_ += B->Drop(); -} - -void BytecodeFlowGraphBuilder::BuildSetFrame() { - if (is_generating_interpreter()) { - UNIMPLEMENTED(); // TODO(alexmarkov): interpreter - } - - // No-op in compiled code. - ASSERT(IsStackEmpty()); -} - -void BytecodeFlowGraphBuilder::BuildEqualsNull() { - BuildDebugStepCheck(); - - ASSERT(scratch_var_ != nullptr); - LoadStackSlots(1); - - TargetEntryInstr* true_branch = nullptr; - TargetEntryInstr* false_branch = nullptr; - code_ += B->BranchIfNull(&true_branch, &false_branch); - - JoinEntryInstr* join = B->BuildJoinEntry(); - - code_ = Fragment(true_branch); - code_ += B->Constant(Bool::True()); - code_ += B->StoreLocalRaw(position_, scratch_var_); - code_ += B->Drop(); - code_ += B->Goto(join); - - code_ = Fragment(false_branch); - code_ += B->Constant(Bool::False()); - code_ += B->StoreLocalRaw(position_, scratch_var_); - code_ += B->Drop(); - code_ += B->Goto(join); - - code_ = Fragment(join); - code_ += B->LoadLocal(scratch_var_); -} - -void BytecodeFlowGraphBuilder::BuildPrimitiveOp( - const String& name, - Token::Kind token_kind, - const AbstractType& static_receiver_type, - int num_args) { - ASSERT((num_args == 1) || (num_args == 2)); - ASSERT(MethodTokenRecognizer::RecognizeTokenKind(name) == token_kind); - - // A DebugStepCheck is performed as part of the calling stub. - - LoadStackSlots(num_args); - InputsArray* arguments = B->GetArguments(num_args); - - InstanceCallInstr* call = new (Z) InstanceCallInstr( - position_, name, token_kind, arguments, 0, Array::null_array(), num_args, - *ic_data_array_, B->GetNextDeoptId()); - - call->set_receivers_static_type(&static_receiver_type); - - code_ <<= call; - B->Push(call); -} - -void BytecodeFlowGraphBuilder::BuildIntOp(const String& name, - Token::Kind token_kind, - int num_args) { - BuildPrimitiveOp(name, token_kind, - AbstractType::ZoneHandle(Z, Type::IntType()), num_args); -} - -void BytecodeFlowGraphBuilder::BuildDoubleOp(const String& name, - Token::Kind token_kind, - int num_args) { - BuildPrimitiveOp(name, token_kind, - AbstractType::ZoneHandle(Z, Type::Double()), num_args); -} - -void BytecodeFlowGraphBuilder::BuildNegateInt() { - BuildIntOp(Symbols::UnaryMinus(), Token::kNEGATE, 1); -} - -void BytecodeFlowGraphBuilder::BuildAddInt() { - BuildIntOp(Symbols::Plus(), Token::kADD, 2); -} - -void BytecodeFlowGraphBuilder::BuildSubInt() { - BuildIntOp(Symbols::Minus(), Token::kSUB, 2); -} - -void BytecodeFlowGraphBuilder::BuildMulInt() { - BuildIntOp(Symbols::Star(), Token::kMUL, 2); -} - -void BytecodeFlowGraphBuilder::BuildTruncDivInt() { - BuildIntOp(Symbols::TruncDivOperator(), Token::kTRUNCDIV, 2); -} - -void BytecodeFlowGraphBuilder::BuildModInt() { - BuildIntOp(Symbols::Percent(), Token::kMOD, 2); -} - -void BytecodeFlowGraphBuilder::BuildBitAndInt() { - BuildIntOp(Symbols::Ampersand(), Token::kBIT_AND, 2); -} - -void BytecodeFlowGraphBuilder::BuildBitOrInt() { - BuildIntOp(Symbols::BitOr(), Token::kBIT_OR, 2); -} - -void BytecodeFlowGraphBuilder::BuildBitXorInt() { - BuildIntOp(Symbols::Caret(), Token::kBIT_XOR, 2); -} - -void BytecodeFlowGraphBuilder::BuildShlInt() { - BuildIntOp(Symbols::LeftShiftOperator(), Token::kSHL, 2); -} - -void BytecodeFlowGraphBuilder::BuildShrInt() { - BuildIntOp(Symbols::RightShiftOperator(), Token::kSHR, 2); -} - -void BytecodeFlowGraphBuilder::BuildCompareIntEq() { - BuildIntOp(Symbols::EqualOperator(), Token::kEQ, 2); -} - -void BytecodeFlowGraphBuilder::BuildCompareIntGt() { - BuildIntOp(Symbols::RAngleBracket(), Token::kGT, 2); -} - -void BytecodeFlowGraphBuilder::BuildCompareIntLt() { - BuildIntOp(Symbols::LAngleBracket(), Token::kLT, 2); -} - -void BytecodeFlowGraphBuilder::BuildCompareIntGe() { - BuildIntOp(Symbols::GreaterEqualOperator(), Token::kGTE, 2); -} - -void BytecodeFlowGraphBuilder::BuildCompareIntLe() { - BuildIntOp(Symbols::LessEqualOperator(), Token::kLTE, 2); -} - -void BytecodeFlowGraphBuilder::BuildNegateDouble() { - BuildDoubleOp(Symbols::UnaryMinus(), Token::kNEGATE, 1); -} - -void BytecodeFlowGraphBuilder::BuildAddDouble() { - BuildDoubleOp(Symbols::Plus(), Token::kADD, 2); -} - -void BytecodeFlowGraphBuilder::BuildSubDouble() { - BuildDoubleOp(Symbols::Minus(), Token::kSUB, 2); -} - -void BytecodeFlowGraphBuilder::BuildMulDouble() { - BuildDoubleOp(Symbols::Star(), Token::kMUL, 2); -} - -void BytecodeFlowGraphBuilder::BuildDivDouble() { - BuildDoubleOp(Symbols::Slash(), Token::kDIV, 2); -} - -void BytecodeFlowGraphBuilder::BuildCompareDoubleEq() { - BuildDoubleOp(Symbols::EqualOperator(), Token::kEQ, 2); -} - -void BytecodeFlowGraphBuilder::BuildCompareDoubleGt() { - BuildDoubleOp(Symbols::RAngleBracket(), Token::kGT, 2); -} - -void BytecodeFlowGraphBuilder::BuildCompareDoubleLt() { - BuildDoubleOp(Symbols::LAngleBracket(), Token::kLT, 2); -} - -void BytecodeFlowGraphBuilder::BuildCompareDoubleGe() { - BuildDoubleOp(Symbols::GreaterEqualOperator(), Token::kGTE, 2); -} - -void BytecodeFlowGraphBuilder::BuildCompareDoubleLe() { - BuildDoubleOp(Symbols::LessEqualOperator(), Token::kLTE, 2); -} - -void BytecodeFlowGraphBuilder::BuildAllocateClosure() { - if (is_generating_interpreter()) { - UNIMPLEMENTED(); // TODO(alexmarkov): interpreter - } - - const Function& target = Function::Cast(ConstantAt(DecodeOperandD()).value()); - code_ += B->AllocateClosure(position_, target); -} - -// Builds graph for a call to 'dart:ffi::_asFunctionInternal'. The stack must -// look like: -// -// => pointer argument -// => signatures -// ... -void BytecodeFlowGraphBuilder::BuildFfiAsFunction() { - // The bytecode FGB doesn't eagerly insert PushArguments, so the type - // arguments won't be wrapped in a PushArgumentsInstr. - const TypeArguments& type_args = - TypeArguments::Cast(B->Peek(/*depth=*/1)->AsConstant()->value()); - // Drop type arguments, preserving pointer. - code_ += B->DropTempsPreserveTop(1); - code_ += B->BuildFfiAsFunctionInternalCall(type_args); -} - -// Builds graph for a call to 'dart:ffi::_nativeCallbackFunction'. -// The call-site must look like this (guaranteed by the FE which inserts it): -// -// _nativeCallbackFunction(target, exceptionalReturn) -// -// Therefore the stack shall look like: -// -// => ensured (by FE) to be a constant -// => closure, ensured (by FE) to be a (non-partially-instantiated) -// static tearoff -// => [NativeSignatureType] -void BytecodeFlowGraphBuilder::BuildFfiNativeCallbackFunction() { - const TypeArguments& type_args = - TypeArguments::Cast(B->Peek(/*depth=*/2)->AsConstant()->value()); - ASSERT(type_args.IsInstantiated() && type_args.Length() == 1); - const Function& native_sig = Function::Handle( - Z, Type::CheckedHandle(Z, type_args.TypeAt(0)).signature()); - - const Closure& target_closure = - Closure::Cast(B->Peek(/*depth=*/1)->AsConstant()->value()); - ASSERT(!target_closure.IsNull()); - Function& target = Function::Handle(Z, target_closure.function()); - ASSERT(!target.IsNull() && target.IsImplicitClosureFunction()); - target = target.parent_function(); - - const Instance& exceptional_return = - Instance::Cast(B->Peek(/*depth=*/0)->AsConstant()->value()); - - const Function& result = - Function::ZoneHandle(Z, compiler::ffi::NativeCallbackFunction( - native_sig, target, exceptional_return)); - code_ += B->Constant(result); - code_ += B->DropTempsPreserveTop(3); -} - -void BytecodeFlowGraphBuilder::BuildDebugStepCheck() { -#if !defined(PRODUCT) - if (build_debug_step_checks_) { - code_ += B->DebugStepCheck(position_); - } -#endif // !defined(PRODUCT) -} - -intptr_t BytecodeFlowGraphBuilder::GetTryIndex(const PcDescriptors& descriptors, - intptr_t pc) { - const uword pc_offset = - KernelBytecode::BytecodePcToOffset(pc, /* is_return_address = */ true); - PcDescriptors::Iterator iter(descriptors, PcDescriptorsLayout::kAnyKind); - intptr_t try_index = kInvalidTryIndex; - while (iter.MoveNext()) { - const intptr_t current_try_index = iter.TryIndex(); - const uword start_pc = iter.PcOffset(); - if (pc_offset < start_pc) { - break; - } - const bool has_next = iter.MoveNext(); - ASSERT(has_next); - const uword end_pc = iter.PcOffset(); - if (start_pc <= pc_offset && pc_offset < end_pc) { - ASSERT(try_index < current_try_index); - try_index = current_try_index; - } - } - return try_index; -} - -JoinEntryInstr* BytecodeFlowGraphBuilder::EnsureControlFlowJoin( - const PcDescriptors& descriptors, - intptr_t pc) { - ASSERT((0 <= pc) && (pc < bytecode_length_)); - JoinEntryInstr* join = jump_targets_.Lookup(pc); - if (join == nullptr) { - join = B->BuildJoinEntry(GetTryIndex(descriptors, pc)); - jump_targets_.Insert(pc, join); - } - return join; -} - -bool BytecodeFlowGraphBuilder::RequiresScratchVar(const KBCInstr* instr) { - switch (KernelBytecode::DecodeOpcode(instr)) { - case KernelBytecode::kEntryOptional: - return KernelBytecode::DecodeC(instr) > 0; - - case KernelBytecode::kEqualsNull: - return true; - - case KernelBytecode::kNativeCall: - case KernelBytecode::kNativeCall_Wide: - return function().recognized_kind() == MethodRecognizer::kListFactory; - - default: - return false; - } -} - -void BytecodeFlowGraphBuilder::CollectControlFlow( - const PcDescriptors& descriptors, - const ExceptionHandlers& handlers, - GraphEntryInstr* graph_entry) { - bool seen_jump_if_unchecked = false; - for (intptr_t pc = 0; pc < bytecode_length_;) { - const KBCInstr* instr = &(raw_bytecode_[pc]); - - if (KernelBytecode::IsJumpOpcode(instr)) { - const intptr_t target = pc + KernelBytecode::DecodeT(instr); - EnsureControlFlowJoin(descriptors, target); - - if (KernelBytecode::IsJumpIfUncheckedOpcode(instr)) { - if (seen_jump_if_unchecked) { - FATAL1( - "Multiple JumpIfUnchecked bytecode instructions are not allowed: " - "%s.", - function().ToFullyQualifiedCString()); - } - seen_jump_if_unchecked = true; - ASSERT(entry_point_style_ == UncheckedEntryPointStyle::kNone); - entry_point_style_ = ChooseEntryPointStyle(instr); - if (entry_point_style_ == - UncheckedEntryPointStyle::kSharedWithVariable) { - parsed_function_->EnsureEntryPointsTemp(); - } - } - } else if (KernelBytecode::IsCheckStackOpcode(instr) && - (KernelBytecode::DecodeA(instr) != 0)) { - // (dartbug.com/36590) BlockEntryInstr::FindOsrEntryAndRelink assumes - // that CheckStackOverflow instruction is at the beginning of a join - // block. - EnsureControlFlowJoin(descriptors, pc); - } - - if ((scratch_var_ == nullptr) && RequiresScratchVar(instr)) { - scratch_var_ = new (Z) - LocalVariable(TokenPosition::kNoSource, TokenPosition::kNoSource, - Symbols::ExprTemp(), Object::dynamic_type()); - } - - pc += (KernelBytecode::Next(instr) - instr); - } - - PcDescriptors::Iterator iter(descriptors, PcDescriptorsLayout::kAnyKind); - while (iter.MoveNext()) { - const intptr_t start_pc = KernelBytecode::OffsetToBytecodePc( - iter.PcOffset(), /* is_return_address = */ true); - EnsureControlFlowJoin(descriptors, start_pc); - - const bool has_next = iter.MoveNext(); - ASSERT(has_next); - const intptr_t end_pc = KernelBytecode::OffsetToBytecodePc( - iter.PcOffset(), /* is_return_address = */ true); - EnsureControlFlowJoin(descriptors, end_pc); - } - - if (handlers.num_entries() > 0) { - B->InlineBailout("kernel::BytecodeFlowGraphBuilder::CollectControlFlow"); - - exception_var_ = new (Z) - LocalVariable(TokenPosition::kNoSource, TokenPosition::kNoSource, - Symbols::ExceptionVar(), Object::dynamic_type()); - stacktrace_var_ = new (Z) - LocalVariable(TokenPosition::kNoSource, TokenPosition::kNoSource, - Symbols::StackTraceVar(), Object::dynamic_type()); - } - - for (intptr_t try_index = 0; try_index < handlers.num_entries(); - ++try_index) { - ExceptionHandlerInfo handler_info; - handlers.GetHandlerInfo(try_index, &handler_info); - - const intptr_t handler_pc = KernelBytecode::OffsetToBytecodePc( - handler_info.handler_pc_offset, /* is_return_address = */ false); - JoinEntryInstr* join = EnsureControlFlowJoin(descriptors, handler_pc); - - // Make sure exception handler starts with SetFrame bytecode instruction. - ASSERT(KernelBytecode::IsSetFrameOpcode(&(raw_bytecode_[handler_pc]))); - - const Array& handler_types = - Array::ZoneHandle(Z, handlers.GetHandledTypes(try_index)); - - CatchBlockEntryInstr* entry = new (Z) CatchBlockEntryInstr( - handler_info.is_generated != 0, B->AllocateBlockId(), - handler_info.outer_try_index, graph_entry, handler_types, try_index, - handler_info.needs_stacktrace != 0, B->GetNextDeoptId(), nullptr, - nullptr, exception_var_, stacktrace_var_); - graph_entry->AddCatchEntry(entry); - - code_ = Fragment(entry); - code_ += B->Goto(join); - } -} - -UncheckedEntryPointStyle BytecodeFlowGraphBuilder::ChooseEntryPointStyle( - const KBCInstr* jump_if_unchecked) { - ASSERT(KernelBytecode::IsJumpIfUncheckedOpcode(jump_if_unchecked)); - - if (!function().MayHaveUncheckedEntryPoint()) { - return UncheckedEntryPointStyle::kNone; - } - - // Separate entry points are used if bytecode has the following pattern: - // Entry - // CheckStack (optional) - // DebugCheck (optional) - // JumpIfUnchecked - // - const KBCInstr* instr = raw_bytecode_; - if (!KernelBytecode::IsEntryOpcode(instr)) { - return UncheckedEntryPointStyle::kSharedWithVariable; - } - instr = KernelBytecode::Next(instr); - if (KernelBytecode::IsCheckStackOpcode(instr)) { - instr = KernelBytecode::Next(instr); - } - if (KernelBytecode::IsDebugCheckOpcode(instr)) { - instr = KernelBytecode::Next(instr); - } - if (instr != jump_if_unchecked) { - return UncheckedEntryPointStyle::kSharedWithVariable; - } - return UncheckedEntryPointStyle::kSeparate; -} - -void BytecodeFlowGraphBuilder::CreateParameterVariables() { - const Bytecode& bytecode = Bytecode::Handle(Z, function().bytecode()); - object_pool_ = bytecode.object_pool(); - bytecode_instr_ = reinterpret_cast(bytecode.PayloadStart()); - - scratch_var_ = parsed_function_->EnsureExpressionTemp(); - - if (KernelBytecode::IsEntryOptionalOpcode(bytecode_instr_)) { - AllocateParametersAndLocalsForEntryOptional(); - } else if (KernelBytecode::IsEntryOpcode(bytecode_instr_)) { - AllocateLocalVariables(DecodeOperandD()); - AllocateFixedParameters(); - } else if (KernelBytecode::IsEntryFixedOpcode(bytecode_instr_)) { - AllocateLocalVariables(DecodeOperandE()); - AllocateFixedParameters(); - } else { - UNREACHABLE(); - } - - if (function().IsGeneric()) { - // For recognized methods we generate the IL by hand. Yet we need to find - // out which [LocalVariable] is holding the function type arguments. We - // scan the bytecode for the CheckFunctionTypeArgs bytecode. - // - // Note that we cannot add an extra local variable for the type argument - // in [AllocateLocalVariables]. We sometimes reuse the same ParsedFunction - // multiple times. For non-recognized generic bytecode functions - // ParsedFunction::RawTypeArgumentsVariable() is set during flow graph - // construction (after local variables are allocated). So the next time, - // if ParsedFunction is reused, we would allocate an extra local variable. - // TODO(alexmarkov): revise how function type args variable is allocated - // and avoid looking at CheckFunctionTypeArgs bytecode. - const KBCInstr* instr = - reinterpret_cast(bytecode.PayloadStart()); - const KBCInstr* end = reinterpret_cast( - bytecode.PayloadStart() + bytecode.Size()); - - LocalVariable* type_args_var = nullptr; - while (instr < end) { - if (KernelBytecode::IsCheckFunctionTypeArgs(instr)) { - const intptr_t expected_num_type_args = KernelBytecode::DecodeA(instr); - if (expected_num_type_args > 0) { // Exclude weird closure case. - type_args_var = LocalVariableAt(KernelBytecode::DecodeE(instr)); - break; - } - } - instr = KernelBytecode::Next(instr); - } - - // Every generic function *must* have a kCheckFunctionTypeArgs bytecode. - ASSERT(type_args_var != nullptr); - - // Normally the flow graph building code of bytecode will, as a side-effect - // of building the flow graph, register the function type arguments variable - // in the [ParsedFunction] (see [BuildCheckFunctionTypeArgs]). - parsed_function_->set_function_type_arguments(type_args_var); - parsed_function_->SetRawTypeArgumentsVariable(type_args_var); - } -} - -intptr_t BytecodeFlowGraphBuilder::UpdateScope( - BytecodeLocalVariablesIterator* iter, - intptr_t pc) { - // Leave scopes that have ended. - while ((current_scope_ != nullptr) && (current_scope_->end_pc_ <= pc)) { - for (LocalVariable* local : current_scope_->hidden_vars_) { - local_vars_[-local->index().value()] = local; - } - current_scope_ = current_scope_->parent_; - } - - // Enter scopes that have started. - intptr_t next_pc = bytecode_length_; - while (!iter->IsDone()) { - if (iter->IsScope()) { - if (iter->StartPC() > pc) { - next_pc = iter->StartPC(); - break; - } - if (iter->EndPC() > pc) { - // Push new scope and declare its variables. - current_scope_ = new (Z) BytecodeScope( - Z, iter->EndPC(), iter->ContextLevel(), current_scope_); - if (!seen_parameters_scope_) { - // Skip variables from the first scope as it may contain variables - // which were used in prologue (parameters, function type arguments). - // The already used variables should not be replaced with new ones. - seen_parameters_scope_ = true; - iter->MoveNext(); - continue; - } - while (iter->MoveNext() && iter->IsVariableDeclaration()) { - const intptr_t index = iter->Index(); - if (!iter->IsCaptured() && (index >= 0)) { - LocalVariable* local = new (Z) LocalVariable( - TokenPosition::kNoSource, TokenPosition::kNoSource, - String::ZoneHandle(Z, iter->Name()), - AbstractType::ZoneHandle(Z, iter->Type())); - local->set_index(VariableIndex(-index)); - ASSERT(local_vars_[index]->index().value() == -index); - current_scope_->hidden_vars_.Add(local_vars_[index]); - local_vars_[index] = local; - } - } - continue; - } - } - iter->MoveNext(); - } - if (current_scope_ != nullptr && next_pc > current_scope_->end_pc_) { - next_pc = current_scope_->end_pc_; - } - B->set_context_depth( - current_scope_ != nullptr ? current_scope_->context_level_ : 0); - return next_pc; -} - -FlowGraph* BytecodeFlowGraphBuilder::BuildGraph() { - const Bytecode& bytecode = Bytecode::Handle(Z, function().bytecode()); - - object_pool_ = bytecode.object_pool(); - raw_bytecode_ = reinterpret_cast(bytecode.PayloadStart()); - bytecode_length_ = bytecode.Size() / sizeof(KBCInstr); - - graph_entry_ = new (Z) GraphEntryInstr(*parsed_function_, B->osr_id_); - - auto normal_entry = B->BuildFunctionEntry(graph_entry_); - graph_entry_->set_normal_entry(normal_entry); - - const PcDescriptors& descriptors = - PcDescriptors::Handle(Z, bytecode.pc_descriptors()); - const ExceptionHandlers& handlers = - ExceptionHandlers::Handle(Z, bytecode.exception_handlers()); - - CollectControlFlow(descriptors, handlers, graph_entry_); - - inferred_types_attribute_ ^= BytecodeReader::GetBytecodeAttribute( - function(), Symbols::vm_inferred_type_metadata()); - - kernel::BytecodeSourcePositionsIterator source_pos_iter(Z, bytecode); - bool update_position = source_pos_iter.MoveNext(); - - kernel::BytecodeLocalVariablesIterator local_vars_iter(Z, bytecode); - intptr_t next_pc_to_update_scope = - local_vars_iter.MoveNext() ? 0 : bytecode_length_; - - code_ = Fragment(normal_entry); - - for (pc_ = 0; pc_ < bytecode_length_; pc_ = next_pc_) { - bytecode_instr_ = &(raw_bytecode_[pc_]); - next_pc_ = pc_ + (KernelBytecode::Next(bytecode_instr_) - bytecode_instr_); - - JoinEntryInstr* join = jump_targets_.Lookup(pc_); - if (join != nullptr) { - Value* stack_state = stack_states_.Lookup(pc_); - if (code_.is_open()) { - if (stack_state != B->stack_) { - ASSERT(stack_state == nullptr); - stack_states_.Insert(pc_, B->stack_); - } - code_ += B->Goto(join); - } else { - ASSERT(IsStackEmpty()); - B->stack_ = stack_state; - } - code_ = Fragment(join); - join->set_stack_depth(B->GetStackDepth()); - B->SetCurrentTryIndex(join->try_index()); - } else { - // Unreachable bytecode is not allowed. - ASSERT(!code_.is_closed()); - } - - while (update_position && - static_cast(pc_) >= source_pos_iter.PcOffset()) { - position_ = source_pos_iter.TokenPos(); - if (source_pos_iter.IsYieldPoint()) { - last_yield_point_pc_ = source_pos_iter.PcOffset(); - ++last_yield_point_index_; - } - update_position = source_pos_iter.MoveNext(); - } - - if (pc_ >= next_pc_to_update_scope) { - next_pc_to_update_scope = UpdateScope(&local_vars_iter, pc_); - } - - BuildInstruction(KernelBytecode::DecodeOpcode(bytecode_instr_)); - - if (code_.is_closed()) { - ASSERT(IsStackEmpty()); - } - } - - // When compiling for OSR, use a depth first search to find the OSR - // entry and make graph entry jump to it instead of normal entry. - // Catch entries are always considered reachable, even if they - // become unreachable after OSR. - if (B->IsCompiledForOsr()) { - graph_entry_->RelinkToOsrEntry(Z, B->last_used_block_id_ + 1); - } - - FlowGraph* flow_graph = new (Z) FlowGraph( - *parsed_function_, graph_entry_, B->last_used_block_id_, prologue_info_); - - if (FLAG_print_flow_graph_from_bytecode) { - FlowGraphPrinter::PrintGraph("Constructed from bytecode", flow_graph); - } - - return flow_graph; -} - -} // namespace kernel -} // namespace dart diff --git a/runtime/vm/compiler/frontend/bytecode_flow_graph_builder.h b/runtime/vm/compiler/frontend/bytecode_flow_graph_builder.h deleted file mode 100644 index c98d743e536..00000000000 --- a/runtime/vm/compiler/frontend/bytecode_flow_graph_builder.h +++ /dev/null @@ -1,252 +0,0 @@ -// Copyright (c) 2018, the Dart project authors. Please see the AUTHORS file -// for details. All rights reserved. Use of this source code is governed by a -// BSD-style license that can be found in the LICENSE file. - -#ifndef RUNTIME_VM_COMPILER_FRONTEND_BYTECODE_FLOW_GRAPH_BUILDER_H_ -#define RUNTIME_VM_COMPILER_FRONTEND_BYTECODE_FLOW_GRAPH_BUILDER_H_ - -#if defined(DART_PRECOMPILED_RUNTIME) -#error "AOT runtime should not use compiler sources (including header files)" -#endif // defined(DART_PRECOMPILED_RUNTIME) - -#include "vm/compiler/backend/il.h" -#include "vm/compiler/frontend/base_flow_graph_builder.h" -#include "vm/compiler/frontend/kernel_translation_helper.h" // For InferredTypeMetadata -#include "vm/constants_kbc.h" - -namespace dart { -namespace kernel { - -class BytecodeLocalVariablesIterator; - -// This class builds flow graph from bytecode. It is used either to compile -// from bytecode, or generate bytecode interpreter (the latter is not -// fully implemented yet). -// TODO(alexmarkov): extend this class and IL to generate an interpreter in -// addition to compiling bytecode. -class BytecodeFlowGraphBuilder { - public: - BytecodeFlowGraphBuilder(BaseFlowGraphBuilder* flow_graph_builder, - ParsedFunction* parsed_function, - ZoneGrowableArray* ic_data_array) - : flow_graph_builder_(flow_graph_builder), - zone_(flow_graph_builder->zone_), - is_generating_interpreter_( - false), // TODO(alexmarkov): pass as argument - parsed_function_(parsed_function), - ic_data_array_(ic_data_array), - object_pool_(ObjectPool::Handle(zone_)), - bytecode_length_(0), - pc_(0), - position_(TokenPosition::kNoSource), - local_vars_(zone_, 0), - parameters_(zone_, 0), - exception_var_(nullptr), - stacktrace_var_(nullptr), - scratch_var_(nullptr), - prologue_info_(-1, -1), - throw_no_such_method_(nullptr), - inferred_types_attribute_(Array::Handle(zone_)) {} - - FlowGraph* BuildGraph(); - - // Create parameter variables without building a flow graph. - void CreateParameterVariables(); - - protected: - // Returns `true` if building a flow graph for a bytecode interpreter, or - // `false` if compiling a function from bytecode. - bool is_generating_interpreter() const { return is_generating_interpreter_; } - - private: - // Operand of bytecode instruction, either intptr_t value (if compiling - // bytecode) or Definition (if generating interpreter). - class Operand { - public: - explicit Operand(Definition* definition) - : definition_(definition), value_(0) { - ASSERT(definition != nullptr); - } - - explicit Operand(intptr_t value) : definition_(nullptr), value_(value) {} - - Definition* definition() const { - ASSERT(definition_ != nullptr); - return definition_; - } - - intptr_t value() const { - ASSERT(definition_ == nullptr); - return value_; - } - - private: - Definition* definition_; - intptr_t value_; - }; - - // Constant from a constant pool. - // It is either Object (if compiling bytecode) or Definition - // (if generating interpreter). - class Constant { - public: - explicit Constant(Definition* definition) - : definition_(definition), value_(Object::null_object()) { - ASSERT(definition != nullptr); - } - - explicit Constant(Zone* zone, const Object& value) - : definition_(nullptr), value_(value) {} - - Definition* definition() const { - ASSERT(definition_ != nullptr); - return definition_; - } - - const Object& value() const { - ASSERT(definition_ == nullptr); - return value_; - } - - private: - Definition* definition_; - const Object& value_; - }; - - // Scope declared in bytecode local variables information. - class BytecodeScope : public ZoneAllocated { - public: - BytecodeScope(Zone* zone, - intptr_t end_pc, - intptr_t context_level, - BytecodeScope* parent) - : end_pc_(end_pc), - context_level_(context_level), - parent_(parent), - hidden_vars_(zone, 4) {} - - const intptr_t end_pc_; - const intptr_t context_level_; - BytecodeScope* const parent_; - ZoneGrowableArray hidden_vars_; - }; - - Operand DecodeOperandA(); - Operand DecodeOperandB(); - Operand DecodeOperandC(); - Operand DecodeOperandD(); - Operand DecodeOperandE(); - Operand DecodeOperandF(); - Operand DecodeOperandX(); - Operand DecodeOperandY(); - Operand DecodeOperandT(); - Constant ConstantAt(Operand entry_index, intptr_t add_index = 0); - void PushConstant(Constant constant); - Constant PopConstant(); - void LoadStackSlots(intptr_t num_slots); - void AllocateLocalVariables(Operand frame_size, - intptr_t num_param_locals = 0); - LocalVariable* AllocateParameter(intptr_t param_index, - VariableIndex var_index); - void AllocateFixedParameters(); - - // Allocates parameters and local variables in case of EntryOptional. - // Returns pointer to the instruction after EntryOptional/LoadConstant/Frame - // bytecodes. - const KBCInstr* AllocateParametersAndLocalsForEntryOptional(); - - LocalVariable* LocalVariableAt(intptr_t local_index); - void StoreLocal(Operand local_index); - void LoadLocal(Operand local_index); - Value* Pop(); - intptr_t GetStackDepth() const; - bool IsStackEmpty() const; - InferredTypeMetadata GetInferredType(intptr_t pc); - void PropagateStackState(intptr_t target_pc); - void DropUnusedValuesFromStack(); - void BuildJumpIfStrictCompare(Token::Kind cmp_kind); - void BuildPrimitiveOp(const String& name, - Token::Kind token_kind, - const AbstractType& static_receiver_type, - int num_args); - void BuildIntOp(const String& name, Token::Kind token_kind, int num_args); - void BuildDoubleOp(const String& name, Token::Kind token_kind, int num_args); - void BuildDirectCallCommon(bool is_unchecked_call); - void BuildInterfaceCallCommon(bool is_unchecked_call, - bool is_instantiated_call); - - void BuildInstruction(KernelBytecode::Opcode opcode); - void BuildFfiAsFunction(); - void BuildFfiNativeCallbackFunction(); - void BuildDebugStepCheck(); - -#define DECLARE_BUILD_METHOD(name, encoding, kind, op1, op2, op3) \ - void Build##name(); - KERNEL_BYTECODES_LIST(DECLARE_BUILD_METHOD) -#undef DECLARE_BUILD_METHOD - - intptr_t GetTryIndex(const PcDescriptors& descriptors, intptr_t pc); - JoinEntryInstr* EnsureControlFlowJoin(const PcDescriptors& descriptors, - intptr_t pc); - bool RequiresScratchVar(const KBCInstr* instr); - void CollectControlFlow(const PcDescriptors& descriptors, - const ExceptionHandlers& handlers, - GraphEntryInstr* graph_entry); - - // Update current scope, context level and local variables for the given PC. - // Returns next PC where scope might need an update. - intptr_t UpdateScope(BytecodeLocalVariablesIterator* iter, intptr_t pc); - - // Figure out entry points style. - UncheckedEntryPointStyle ChooseEntryPointStyle( - const KBCInstr* jump_if_unchecked); - - Thread* thread() const { return flow_graph_builder_->thread_; } - Isolate* isolate() const { return thread()->isolate(); } - - ParsedFunction* parsed_function() const { - ASSERT(!is_generating_interpreter()); - return parsed_function_; - } - const Function& function() const { return parsed_function()->function(); } - - BaseFlowGraphBuilder* flow_graph_builder_; - Zone* zone_; - bool is_generating_interpreter_; - - // The following members are available only when compiling bytecode. - - ParsedFunction* parsed_function_; - ZoneGrowableArray* ic_data_array_; - ObjectPool& object_pool_; - const KBCInstr* raw_bytecode_ = nullptr; - intptr_t bytecode_length_; - intptr_t pc_; - intptr_t next_pc_ = -1; - const KBCInstr* bytecode_instr_ = nullptr; - TokenPosition position_; - intptr_t last_yield_point_pc_ = 0; - intptr_t last_yield_point_index_ = 0; - Fragment code_; - ZoneGrowableArray local_vars_; - ZoneGrowableArray parameters_; - LocalVariable* exception_var_; - LocalVariable* stacktrace_var_; - LocalVariable* scratch_var_; - IntMap jump_targets_; - IntMap stack_states_; - PrologueInfo prologue_info_; - JoinEntryInstr* throw_no_such_method_; - GraphEntryInstr* graph_entry_ = nullptr; - UncheckedEntryPointStyle entry_point_style_ = UncheckedEntryPointStyle::kNone; - bool build_debug_step_checks_ = false; - bool seen_parameters_scope_ = false; - BytecodeScope* current_scope_ = nullptr; - Array& inferred_types_attribute_; - intptr_t inferred_types_index_ = 0; -}; - -} // namespace kernel -} // namespace dart - -#endif // RUNTIME_VM_COMPILER_FRONTEND_BYTECODE_FLOW_GRAPH_BUILDER_H_ diff --git a/runtime/vm/compiler/frontend/bytecode_reader.cc b/runtime/vm/compiler/frontend/bytecode_reader.cc deleted file mode 100644 index a6a4252d4ac..00000000000 --- a/runtime/vm/compiler/frontend/bytecode_reader.cc +++ /dev/null @@ -1,3776 +0,0 @@ -// Copyright (c) 2018, the Dart project authors. Please see the AUTHORS file -// for details. All rights reserved. Use of this source code is governed by a -// BSD-style license that can be found in the LICENSE file. - -#include "vm/compiler/frontend/bytecode_reader.h" - -#include "vm/bit_vector.h" -#include "vm/bootstrap.h" -#include "vm/class_finalizer.h" -#include "vm/class_id.h" -#include "vm/code_descriptors.h" -#include "vm/compiler/aot/precompiler.h" // For Obfuscator -#include "vm/compiler/assembler/disassembler_kbc.h" -#include "vm/compiler/frontend/bytecode_scope_builder.h" -#include "vm/constants_kbc.h" -#include "vm/dart_api_impl.h" // For Api::IsFfiEnabled(). -#include "vm/dart_entry.h" -#include "vm/debugger.h" -#include "vm/flags.h" -#include "vm/hash.h" -#include "vm/longjump.h" -#include "vm/object_store.h" -#include "vm/resolver.h" -#include "vm/reusable_handles.h" -#include "vm/scopes.h" -#include "vm/stack_frame_kbc.h" -#include "vm/timeline.h" - -#define Z (zone_) -#define H (translation_helper_) -#define I (translation_helper_.isolate()) - -namespace dart { - -DEFINE_FLAG(bool, dump_kernel_bytecode, false, "Dump kernel bytecode"); - -namespace kernel { - -BytecodeMetadataHelper::BytecodeMetadataHelper(KernelReaderHelper* helper, - ActiveClass* active_class) - : MetadataHelper(helper, tag(), /* precompiler_only = */ false), - active_class_(active_class) {} - -void BytecodeMetadataHelper::ParseBytecodeFunction( - ParsedFunction* parsed_function) { - TIMELINE_DURATION(Thread::Current(), CompilerVerbose, - "BytecodeMetadataHelper::ParseBytecodeFunction"); - - const Function& function = parsed_function->function(); - ASSERT(function.is_declared_in_bytecode()); - - BytecodeComponentData bytecode_component( - &Array::Handle(helper_->zone_, GetBytecodeComponent())); - BytecodeReaderHelper bytecode_reader(&H, active_class_, &bytecode_component); - - bytecode_reader.ParseBytecodeFunction(parsed_function, function); -} - -bool BytecodeMetadataHelper::ReadLibraries() { - TIMELINE_DURATION(Thread::Current(), Compiler, - "BytecodeMetadataHelper::ReadLibraries"); - ASSERT(Thread::Current()->IsMutatorThread()); - - if (translation_helper_.GetBytecodeComponent() == Array::null()) { - return false; - } - - BytecodeComponentData bytecode_component( - &Array::Handle(helper_->zone_, GetBytecodeComponent())); - - BytecodeReaderHelper bytecode_reader(&H, active_class_, &bytecode_component); - AlternativeReadingScope alt(&bytecode_reader.reader(), - bytecode_component.GetLibraryIndexOffset()); - bytecode_reader.ReadLibraryDeclarations(bytecode_component.GetNumLibraries()); - return true; -} - -void BytecodeMetadataHelper::ReadLibrary(const Library& library) { - TIMELINE_DURATION(Thread::Current(), Compiler, - "BytecodeMetadataHelper::ReadLibrary"); - ASSERT(Thread::Current()->IsMutatorThread()); - ASSERT(!library.Loaded()); - - if (translation_helper_.GetBytecodeComponent() == Array::null()) { - return; - } - - BytecodeComponentData bytecode_component( - &Array::Handle(helper_->zone_, GetBytecodeComponent())); - BytecodeReaderHelper bytecode_reader(&H, active_class_, &bytecode_component); - AlternativeReadingScope alt(&bytecode_reader.reader(), - bytecode_component.GetLibraryIndexOffset()); - bytecode_reader.FindAndReadSpecificLibrary( - library, bytecode_component.GetNumLibraries()); -} - -bool BytecodeMetadataHelper::FindModifiedLibrariesForHotReload( - BitVector* modified_libs, - bool* is_empty_program, - intptr_t* p_num_classes, - intptr_t* p_num_procedures) { - ASSERT(Thread::Current()->IsMutatorThread()); - - if (translation_helper_.GetBytecodeComponent() == Array::null()) { - return false; - } - - BytecodeComponentData bytecode_component( - &Array::Handle(helper_->zone_, GetBytecodeComponent())); - BytecodeReaderHelper bytecode_reader(&H, active_class_, &bytecode_component); - AlternativeReadingScope alt(&bytecode_reader.reader(), - bytecode_component.GetLibraryIndexOffset()); - bytecode_reader.FindModifiedLibrariesForHotReload( - modified_libs, bytecode_component.GetNumLibraries()); - - if (is_empty_program != nullptr) { - *is_empty_program = (bytecode_component.GetNumLibraries() == 0); - } - if (p_num_classes != nullptr) { - *p_num_classes = bytecode_component.GetNumClasses(); - } - if (p_num_procedures != nullptr) { - *p_num_procedures = bytecode_component.GetNumCodes(); - } - return true; -} - -LibraryPtr BytecodeMetadataHelper::GetMainLibrary() { - const intptr_t md_offset = GetComponentMetadataPayloadOffset(); - if (md_offset < 0) { - return Library::null(); - } - - BytecodeComponentData bytecode_component( - &Array::Handle(helper_->zone_, GetBytecodeComponent())); - const intptr_t main_offset = bytecode_component.GetMainOffset(); - if (main_offset == 0) { - return Library::null(); - } - - BytecodeReaderHelper bytecode_reader(&H, active_class_, &bytecode_component); - AlternativeReadingScope alt(&bytecode_reader.reader(), main_offset); - return bytecode_reader.ReadMain(); -} - -ArrayPtr BytecodeMetadataHelper::GetBytecodeComponent() { - ArrayPtr array = translation_helper_.GetBytecodeComponent(); - if (array == Array::null()) { - array = ReadBytecodeComponent(); - ASSERT(array != Array::null()); - } - return array; -} - -ArrayPtr BytecodeMetadataHelper::ReadBytecodeComponent() { - const intptr_t md_offset = GetComponentMetadataPayloadOffset(); - if (md_offset < 0) { - return Array::null(); - } - - BytecodeReaderHelper component_reader(&H, nullptr, nullptr); - return component_reader.ReadBytecodeComponent(md_offset); -} - -BytecodeReaderHelper::BytecodeReaderHelper( - TranslationHelper* translation_helper, - ActiveClass* active_class, - BytecodeComponentData* bytecode_component) - : reader_(translation_helper->metadata_payloads()), - translation_helper_(*translation_helper), - active_class_(active_class), - thread_(translation_helper->thread()), - zone_(translation_helper->zone()), - bytecode_component_(bytecode_component), - scoped_function_(Function::Handle(translation_helper->zone())), - scoped_function_name_(String::Handle(translation_helper->zone())), - scoped_function_class_(Class::Handle(translation_helper->zone())) {} - -void BytecodeReaderHelper::ReadCode(const Function& function, - intptr_t code_offset) { - ASSERT(Thread::Current()->IsMutatorThread()); - ASSERT(!function.IsImplicitGetterFunction() && - !function.IsImplicitSetterFunction()); - if (code_offset == 0) { - FATAL2("Function %s (kind %s) doesn't have bytecode", - function.ToFullyQualifiedCString(), - Function::KindToCString(function.kind())); - } - - AlternativeReadingScope alt(&reader_, code_offset); - // This scope is needed to set active_class_->enclosing_ which is used to - // assign parent function for function types. - ActiveEnclosingFunctionScope active_enclosing_function(active_class_, - &function); - - const intptr_t flags = reader_.ReadUInt(); - const bool has_exceptions_table = - (flags & Code::kHasExceptionsTableFlag) != 0; - const bool has_source_positions = - (flags & Code::kHasSourcePositionsFlag) != 0; - const bool has_local_variables = (flags & Code::kHasLocalVariablesFlag) != 0; - const bool has_nullable_fields = (flags & Code::kHasNullableFieldsFlag) != 0; - const bool has_closures = (flags & Code::kHasClosuresFlag) != 0; - const bool has_parameter_flags = (flags & Code::kHasParameterFlagsFlag) != 0; - const bool has_forwarding_stub_target = - (flags & Code::kHasForwardingStubTargetFlag) != 0; - const bool has_default_function_type_args = - (flags & Code::kHasDefaultFunctionTypeArgsFlag) != 0; - - if (has_parameter_flags) { - intptr_t num_flags = reader_.ReadUInt(); - for (intptr_t i = 0; i < num_flags; ++i) { - reader_.ReadUInt(); - } - } - if (has_forwarding_stub_target) { - reader_.ReadUInt(); - } - if (has_default_function_type_args) { - reader_.ReadUInt(); - } - - intptr_t num_closures = 0; - if (has_closures) { - num_closures = reader_.ReadListLength(); - closures_ = &Array::Handle(Z, Array::New(num_closures)); - for (intptr_t i = 0; i < num_closures; i++) { - ReadClosureDeclaration(function, i); - } - } - - // Create object pool and read pool entries. - const intptr_t obj_count = reader_.ReadListLength(); - const ObjectPool& pool = ObjectPool::Handle(Z, ObjectPool::New(obj_count)); - ReadConstantPool(function, pool, 0); - - // Read bytecode and attach to function. - const Bytecode& bytecode = Bytecode::Handle(Z, ReadBytecode(pool)); - function.AttachBytecode(bytecode); - ASSERT(bytecode.GetBinary(Z) == reader_.typed_data()->raw()); - - ReadExceptionsTable(bytecode, has_exceptions_table); - - ReadSourcePositions(bytecode, has_source_positions); - - ReadLocalVariables(bytecode, has_local_variables); - - if (FLAG_dump_kernel_bytecode) { - KernelBytecodeDisassembler::Disassemble(function); - } - - // Initialization of fields with null literal is elided from bytecode. - // Record the corresponding stores if field guards are enabled. - if (has_nullable_fields) { - ASSERT(function.IsGenerativeConstructor()); - const intptr_t num_fields = reader_.ReadListLength(); - if (I->use_field_guards()) { - Field& field = Field::Handle(Z); - for (intptr_t i = 0; i < num_fields; i++) { - field ^= ReadObject(); - field.RecordStore(Object::null_object()); - } - } else { - for (intptr_t i = 0; i < num_fields; i++) { - ReadObject(); - } - } - } - - // Read closures. - if (has_closures) { - Function& closure = Function::Handle(Z); - Bytecode& closure_bytecode = Bytecode::Handle(Z); - for (intptr_t i = 0; i < num_closures; i++) { - closure ^= closures_->At(i); - - const intptr_t flags = reader_.ReadUInt(); - const bool has_exceptions_table = - (flags & ClosureCode::kHasExceptionsTableFlag) != 0; - const bool has_source_positions = - (flags & ClosureCode::kHasSourcePositionsFlag) != 0; - const bool has_local_variables = - (flags & ClosureCode::kHasLocalVariablesFlag) != 0; - - // Read closure bytecode and attach to closure function. - closure_bytecode = ReadBytecode(pool); - closure.AttachBytecode(closure_bytecode); - ASSERT(bytecode.GetBinary(Z) == reader_.typed_data()->raw()); - - ReadExceptionsTable(closure_bytecode, has_exceptions_table); - - ReadSourcePositions(closure_bytecode, has_source_positions); - - ReadLocalVariables(closure_bytecode, has_local_variables); - - if (FLAG_dump_kernel_bytecode) { - KernelBytecodeDisassembler::Disassemble(closure); - } - -#if !defined(PRODUCT) - thread_->isolate()->debugger()->NotifyBytecodeLoaded(closure); -#endif - } - } - -#if !defined(PRODUCT) - thread_->isolate()->debugger()->NotifyBytecodeLoaded(function); -#endif -} - -static intptr_t IndexFor(Zone* zone, - const Function& function, - const String& name) { - const Bytecode& bc = Bytecode::Handle(zone, function.bytecode()); - const ObjectPool& pool = ObjectPool::Handle(zone, bc.object_pool()); - const KBCInstr* pc = reinterpret_cast(bc.PayloadStart()); - - ASSERT(KernelBytecode::IsEntryOptionalOpcode(pc)); - ASSERT(KernelBytecode::DecodeB(pc) == - function.NumOptionalPositionalParameters()); - ASSERT(KernelBytecode::DecodeC(pc) == function.NumOptionalNamedParameters()); - pc = KernelBytecode::Next(pc); - - const intptr_t num_opt_params = function.NumOptionalParameters(); - const intptr_t num_fixed_params = function.num_fixed_parameters(); - for (intptr_t i = 0; i < num_opt_params; i++) { - const KBCInstr* load_name = pc; - const KBCInstr* load_value = KernelBytecode::Next(load_name); - pc = KernelBytecode::Next(load_value); - ASSERT(KernelBytecode::IsLoadConstantOpcode(load_name)); - ASSERT(KernelBytecode::IsLoadConstantOpcode(load_value)); - if (pool.ObjectAt(KernelBytecode::DecodeE(load_name)) == name.raw()) { - return num_fixed_params + i; - } - } - - UNREACHABLE(); - return -1; -} - -ArrayPtr BytecodeReaderHelper::CreateForwarderChecks(const Function& function) { - ASSERT(function.kind() != FunctionLayout::kDynamicInvocationForwarder); - ASSERT(function.is_declared_in_bytecode()); - - TypeArguments& default_args = TypeArguments::Handle(Z); - if (function.bytecode_offset() != 0) { - AlternativeReadingScope alt(&reader_, function.bytecode_offset()); - - const intptr_t flags = reader_.ReadUInt(); - const bool has_parameter_flags = - (flags & Code::kHasParameterFlagsFlag) != 0; - const bool has_forwarding_stub_target = - (flags & Code::kHasForwardingStubTargetFlag) != 0; - const bool has_default_function_type_args = - (flags & Code::kHasDefaultFunctionTypeArgsFlag) != 0; - - if (has_parameter_flags) { - intptr_t num_flags = reader_.ReadUInt(); - for (intptr_t i = 0; i < num_flags; ++i) { - reader_.ReadUInt(); - } - } - if (has_forwarding_stub_target) { - reader_.ReadUInt(); - } - - if (has_default_function_type_args) { - const intptr_t index = reader_.ReadUInt(); - const Bytecode& code = Bytecode::Handle(Z, function.bytecode()); - const ObjectPool& pool = ObjectPool::Handle(Z, code.object_pool()); - default_args ^= pool.ObjectAt(index); - } - } - - auto& name = String::Handle(Z); - auto& check = ParameterTypeCheck::Handle(Z); - auto& checks = GrowableObjectArray::Handle(Z, GrowableObjectArray::New()); - - checks.Add(function); - checks.Add(default_args); - - const auto& type_params = - TypeArguments::Handle(Z, function.type_parameters()); - if (!type_params.IsNull()) { - auto& type_param = TypeParameter::Handle(Z); - auto& bound = AbstractType::Handle(Z); - for (intptr_t i = 0, n = type_params.Length(); i < n; ++i) { - type_param ^= type_params.TypeAt(i); - bound = type_param.bound(); - if (!bound.IsTopTypeForSubtyping() && - !type_param.IsGenericCovariantImpl()) { - name = type_param.name(); - ASSERT(type_param.IsFinalized()); - check = ParameterTypeCheck::New(); - check.set_param(type_param); - check.set_type_or_bound(bound); - check.set_name(name); - checks.Add(check); - } - } - } - - const intptr_t num_params = function.NumParameters(); - const intptr_t num_pos_params = function.HasOptionalNamedParameters() - ? function.num_fixed_parameters() - : num_params; - - BitVector is_covariant(Z, num_params); - BitVector is_generic_covariant_impl(Z, num_params); - ReadParameterCovariance(function, &is_covariant, &is_generic_covariant_impl); - - auto& type = AbstractType::Handle(Z); - auto& cache = SubtypeTestCache::Handle(Z); - const bool has_optional_parameters = function.HasOptionalParameters(); - for (intptr_t i = function.NumImplicitParameters(); i < num_params; ++i) { - type = function.ParameterTypeAt(i); - if (!type.IsTopTypeForSubtyping() && - !is_generic_covariant_impl.Contains(i) && !is_covariant.Contains(i)) { - name = function.ParameterNameAt(i); - intptr_t index; - if (i >= num_pos_params) { - // Named parameter. - index = IndexFor(Z, function, name); - } else if (has_optional_parameters) { - // Fixed or optional parameter. - index = i; - } else { - // Fixed parameter. - index = -kKBCParamEndSlotFromFp - num_params + i; - } - check = ParameterTypeCheck::New(); - check.set_index(index); - check.set_type_or_bound(type); - check.set_name(name); - cache = SubtypeTestCache::New(); - check.set_cache(cache); - checks.Add(check); - } - } - - return Array::MakeFixedLength(checks); -} - -void BytecodeReaderHelper::ReadClosureDeclaration(const Function& function, - intptr_t closureIndex) { - // Closure flags, must be in sync with ClosureDeclaration constants in - // pkg/vm/lib/bytecode/declarations.dart. - const int kHasOptionalPositionalParamsFlag = 1 << 0; - const int kHasOptionalNamedParamsFlag = 1 << 1; - const int kHasTypeParamsFlag = 1 << 2; - const int kHasSourcePositionsFlag = 1 << 3; - const int kIsAsyncFlag = 1 << 4; - const int kIsAsyncStarFlag = 1 << 5; - const int kIsSyncStarFlag = 1 << 6; - const int kIsDebuggableFlag = 1 << 7; - const int kHasAttributesFlag = 1 << 8; - const int kHasParameterFlagsFlag = 1 << 9; - - const intptr_t flags = reader_.ReadUInt(); - - Object& parent = Object::Handle(Z, ReadObject()); - if (!parent.IsFunction()) { - ASSERT(parent.IsField()); - ASSERT(function.kind() == FunctionLayout::kFieldInitializer); - // Closure in a static field initializer, so use current function as parent. - parent = function.raw(); - } - - String& name = String::CheckedHandle(Z, ReadObject()); - ASSERT(name.IsSymbol()); - - TokenPosition position = TokenPosition::kNoSource; - TokenPosition end_position = TokenPosition::kNoSource; - if ((flags & kHasSourcePositionsFlag) != 0) { - position = reader_.ReadPosition(); - end_position = reader_.ReadPosition(); - } - - const Function& closure = Function::Handle( - Z, Function::NewClosureFunction(name, Function::Cast(parent), position)); - - closure.set_is_declared_in_bytecode(true); - closure.set_end_token_pos(end_position); - - if ((flags & kIsSyncStarFlag) != 0) { - closure.set_modifier(FunctionLayout::kSyncGen); - } else if ((flags & kIsAsyncFlag) != 0) { - closure.set_modifier(FunctionLayout::kAsync); - closure.set_is_inlinable(!FLAG_causal_async_stacks && - !FLAG_lazy_async_stacks); - } else if ((flags & kIsAsyncStarFlag) != 0) { - closure.set_modifier(FunctionLayout::kAsyncGen); - closure.set_is_inlinable(!FLAG_causal_async_stacks && - !FLAG_lazy_async_stacks); - } - if (Function::Cast(parent).IsAsyncOrGenerator()) { - closure.set_is_generated_body(true); - } - closure.set_is_debuggable((flags & kIsDebuggableFlag) != 0); - - closures_->SetAt(closureIndex, closure); - - Type& signature_type = Type::Handle( - Z, ReadFunctionSignature( - closure, (flags & kHasOptionalPositionalParamsFlag) != 0, - (flags & kHasOptionalNamedParamsFlag) != 0, - (flags & kHasTypeParamsFlag) != 0, - /* has_positional_param_names = */ true, - (flags & kHasParameterFlagsFlag) != 0, Nullability::kNonNullable)); - - closure.SetSignatureType(signature_type); - - if ((flags & kHasAttributesFlag) != 0) { - ReadAttributes(closure); - } - - I->AddClosureFunction(closure); -} - -static bool IsNonCanonical(const AbstractType& type) { - return type.IsTypeRef() || (type.IsType() && !type.IsCanonical()); -} - -static bool HasNonCanonicalTypes(Zone* zone, const Function& func) { - auto& type = AbstractType::Handle(zone); - for (intptr_t i = 0; i < func.NumParameters(); ++i) { - type = func.ParameterTypeAt(i); - if (IsNonCanonical(type)) { - return true; - } - } - type = func.result_type(); - if (IsNonCanonical(type)) { - return true; - } - const auto& type_params = TypeArguments::Handle(zone, func.type_parameters()); - if (!type_params.IsNull()) { - for (intptr_t i = 0; i < type_params.Length(); ++i) { - type = type_params.TypeAt(i); - type = TypeParameter::Cast(type).bound(); - if (IsNonCanonical(type)) { - return true; - } - } - } - return false; -} - -TypePtr BytecodeReaderHelper::ReadFunctionSignature( - const Function& func, - bool has_optional_positional_params, - bool has_optional_named_params, - bool has_type_params, - bool has_positional_param_names, - bool has_parameter_flags, - Nullability nullability) { - FunctionTypeScope function_type_scope(this); - - if (has_type_params) { - ReadTypeParametersDeclaration(Class::Handle(Z), func); - } - - const intptr_t kImplicitClosureParam = 1; - const intptr_t num_params = kImplicitClosureParam + reader_.ReadUInt(); - - intptr_t num_required_params = num_params; - if (has_optional_positional_params || has_optional_named_params) { - num_required_params = kImplicitClosureParam + reader_.ReadUInt(); - } - - func.set_num_fixed_parameters(num_required_params); - func.SetNumOptionalParameters(num_params - num_required_params, - !has_optional_named_params); - func.set_parameter_types( - Array::Handle(Z, Array::New(num_params, Heap::kOld))); - func.CreateNameArrayIncludingFlags(Heap::kOld); - - intptr_t i = 0; - func.SetParameterTypeAt(i, AbstractType::dynamic_type()); - func.SetParameterNameAt(i, Symbols::ClosureParameter()); - ++i; - - AbstractType& type = AbstractType::Handle(Z); - String& name = String::Handle(Z); - for (; i < num_params; ++i) { - if (has_positional_param_names || - (has_optional_named_params && (i >= num_required_params))) { - name ^= ReadObject(); - } else { - name = Symbols::NotNamed().raw(); - } - func.SetParameterNameAt(i, name); - type ^= ReadObject(); - func.SetParameterTypeAt(i, type); - } - if (has_parameter_flags) { - intptr_t num_flags = reader_.ReadUInt(); - for (intptr_t i = 0; i < num_flags; ++i) { - intptr_t flag = reader_.ReadUInt(); - if ((flag & Parameter::kIsRequiredFlag) != 0) { - RELEASE_ASSERT(kImplicitClosureParam + i >= num_required_params); - func.SetIsRequiredAt(kImplicitClosureParam + i); - } - } - } - func.TruncateUnusedParameterFlags(); - - type ^= ReadObject(); - func.set_result_type(type); - - // Finalize function type. - type = func.SignatureType(nullability); - ClassFinalizer::FinalizationKind finalization = ClassFinalizer::kCanonicalize; - if (pending_recursive_types_ != nullptr && HasNonCanonicalTypes(Z, func)) { - // This function type is a part of recursive type. Avoid canonicalization - // as not all TypeRef objects are filled up at this point. - finalization = ClassFinalizer::kFinalize; - } - type = ClassFinalizer::FinalizeType(type, finalization); - return Type::Cast(type).raw(); -} - -void BytecodeReaderHelper::ReadTypeParametersDeclaration( - const Class& parameterized_class, - const Function& parameterized_function) { - ASSERT(parameterized_class.IsNull() != parameterized_function.IsNull()); - - const intptr_t num_type_params = reader_.ReadUInt(); - ASSERT(num_type_params > 0); - - intptr_t offset; - NNBDMode nnbd_mode; - if (!parameterized_class.IsNull()) { - offset = parameterized_class.NumTypeArguments() - num_type_params; - nnbd_mode = parameterized_class.nnbd_mode(); - } else { - offset = parameterized_function.NumParentTypeParameters(); - nnbd_mode = parameterized_function.nnbd_mode(); - } - const Nullability nullability = (nnbd_mode == NNBDMode::kOptedInLib) - ? Nullability::kNonNullable - : Nullability::kLegacy; - - // First setup the type parameters, so if any of the following code uses it - // (in a recursive way) we're fine. - // - // Step a) Create array of [TypeParameter] objects (without bound). - const TypeArguments& type_parameters = - TypeArguments::Handle(Z, TypeArguments::New(num_type_params)); - String& name = String::Handle(Z); - TypeParameter& parameter = TypeParameter::Handle(Z); - AbstractType& type = AbstractType::Handle(Z); - for (intptr_t i = 0; i < num_type_params; ++i) { - name ^= ReadObject(); - ASSERT(name.IsSymbol()); - parameter = TypeParameter::New(parameterized_class, parameterized_function, - i, name, /* bound = */ type, - /* is_generic_covariant_impl = */ false, - nullability, TokenPosition::kNoSource); - parameter.set_index(offset + i); - parameter.SetIsFinalized(); - parameter.SetCanonical(); - parameter.SetDeclaration(true); - // For functions, default type arguments aren't available here but with the - // bytecode, so update any non-dynamic default arguments when reading the - // bytecode. (For classes, we don't currently use this, so dynamic is fine.) - parameter.set_default_argument(Object::dynamic_type()); - type_parameters.SetTypeAt(i, parameter); - } - - if (!parameterized_class.IsNull()) { - parameterized_class.set_type_parameters(type_parameters); - } else if (!parameterized_function.IsFactory()) { - // Do not set type parameters for factories, as VM uses class type - // parameters instead. - parameterized_function.set_type_parameters(type_parameters); - parameterized_function.UpdateCachedDefaultTypeArguments(thread_); - if (parameterized_function.IsSignatureFunction()) { - if (function_type_type_parameters_ == nullptr) { - function_type_type_parameters_ = &type_parameters; - } else { - function_type_type_parameters_ = &TypeArguments::Handle( - Z, function_type_type_parameters_->ConcatenateTypeParameters( - Z, type_parameters)); - } - } else { - ASSERT(function_type_type_parameters_ == nullptr); - } - } - - // Step b) Fill in the bounds of all [TypeParameter]s. - for (intptr_t i = 0; i < num_type_params; ++i) { - parameter ^= type_parameters.TypeAt(i); - type ^= ReadObject(); - // Convert dynamic to Object? or Object* in bounds of type parameters so - // they are equivalent when doing subtype checks for function types. - // TODO(https://github.com/dart-lang/language/issues/495): revise this - // when function subtyping is fixed. - if (type.IsDynamicType()) { - type = nnbd_mode == NNBDMode::kOptedInLib - ? I->object_store()->nullable_object_type() - : I->object_store()->legacy_object_type(); - } - parameter.set_bound(type); - } - - // Fix bounds in all derived type parameters (with different nullabilities). - if (active_class_->derived_type_parameters != nullptr) { - auto& derived = TypeParameter::Handle(Z); - for (intptr_t i = 0, n = active_class_->derived_type_parameters->Length(); - i < n; ++i) { - derived ^= active_class_->derived_type_parameters->At(i); - if (derived.bound() == AbstractType::null() && - ((!parameterized_class.IsNull() && - derived.parameterized_class() == parameterized_class.raw()) || - (!parameterized_function.IsNull() && - derived.parameterized_function() == - parameterized_function.raw()))) { - ASSERT(derived.IsFinalized()); - parameter ^= type_parameters.TypeAt(derived.index() - offset); - type = parameter.bound(); - derived.set_bound(type); - type = parameter.default_argument(); - derived.set_default_argument(type); - } - } - } -} - -intptr_t BytecodeReaderHelper::ReadConstantPool(const Function& function, - const ObjectPool& pool, - intptr_t start_index) { - TIMELINE_DURATION(Thread::Current(), CompilerVerbose, - "BytecodeReaderHelper::ReadConstantPool"); - - // These enums and the code below reading the constant pool from kernel must - // be kept in sync with pkg/vm/lib/bytecode/constant_pool.dart. - enum ConstantPoolTag { - kInvalid, - kUnused1, - kUnused2, - kUnused3, - kUnused4, - kUnused5, - kUnused6, - kUnused6a, - kUnused7, - kStaticField, - kInstanceField, - kClass, - kTypeArgumentsField, - kUnused8, - kType, - kUnused9, - kUnused10, - kUnused11, - kUnused12, - kClosureFunction, - kEndClosureFunctionScope, - kNativeEntry, - kSubtypeTestCache, - kUnused13, - kEmptyTypeArguments, - kUnused14, - kUnused15, - kObjectRef, - kDirectCall, - kInterfaceCall, - kInstantiatedInterfaceCall, - kDynamicCall, - kDirectCallViaDynamicForwarder, - }; - - Object& obj = Object::Handle(Z); - Object& elem = Object::Handle(Z); - Field& field = Field::Handle(Z); - Class& cls = Class::Handle(Z); - String& name = String::Handle(Z); - const intptr_t obj_count = pool.Length(); - for (intptr_t i = start_index; i < obj_count; ++i) { - const intptr_t tag = reader_.ReadTag(); - switch (tag) { - case ConstantPoolTag::kInvalid: - UNREACHABLE(); - case ConstantPoolTag::kStaticField: - obj = ReadObject(); - ASSERT(obj.IsField()); - break; - case ConstantPoolTag::kInstanceField: - field ^= ReadObject(); - // InstanceField constant occupies 2 entries. - // The first entry is used for field offset. - obj = Smi::New(field.HostOffset() / kWordSize); - pool.SetTypeAt(i, ObjectPool::EntryType::kTaggedObject, - ObjectPool::Patchability::kNotPatchable); - pool.SetObjectAt(i, obj); - ++i; - ASSERT(i < obj_count); - // The second entry is used for field object. - obj = field.raw(); - break; - case ConstantPoolTag::kClass: - obj = ReadObject(); - ASSERT(obj.IsClass()); - break; - case ConstantPoolTag::kTypeArgumentsField: - cls ^= ReadObject(); - obj = Smi::New(cls.host_type_arguments_field_offset() / kWordSize); - break; - case ConstantPoolTag::kType: - obj = ReadObject(); - ASSERT(obj.IsAbstractType()); - break; - case ConstantPoolTag::kClosureFunction: { - intptr_t closure_index = reader_.ReadUInt(); - obj = closures_->At(closure_index); - ASSERT(obj.IsFunction()); - // Set current entry. - pool.SetTypeAt(i, ObjectPool::EntryType::kTaggedObject, - ObjectPool::Patchability::kNotPatchable); - pool.SetObjectAt(i, obj); - - // This scope is needed to set active_class_->enclosing_ which is used - // to assign parent function for function types. - ActiveEnclosingFunctionScope active_enclosing_function( - active_class_, &Function::Cast(obj)); - - // Read constant pool until corresponding EndClosureFunctionScope. - i = ReadConstantPool(function, pool, i + 1); - - // Proceed with the rest of entries. - continue; - } - case ConstantPoolTag::kEndClosureFunctionScope: { - // EndClosureFunctionScope entry is not used and set to null. - obj = Object::null(); - pool.SetTypeAt(i, ObjectPool::EntryType::kTaggedObject, - ObjectPool::Patchability::kNotPatchable); - pool.SetObjectAt(i, obj); - return i; - } - case ConstantPoolTag::kNativeEntry: { - name = ReadString(); - obj = NativeEntry(function, name); - pool.SetTypeAt(i, ObjectPool::EntryType::kNativeEntryData, - ObjectPool::Patchability::kNotPatchable); - pool.SetObjectAt(i, obj); - continue; - } - case ConstantPoolTag::kSubtypeTestCache: { - obj = SubtypeTestCache::New(); - } break; - case ConstantPoolTag::kEmptyTypeArguments: - obj = Object::empty_type_arguments().raw(); - break; - case ConstantPoolTag::kObjectRef: - obj = ReadObject(); - break; - case ConstantPoolTag::kDirectCall: { - // DirectCall constant occupies 2 entries. - // The first entry is used for target function. - obj = ReadObject(); - ASSERT(obj.IsFunction()); - pool.SetTypeAt(i, ObjectPool::EntryType::kTaggedObject, - ObjectPool::Patchability::kNotPatchable); - pool.SetObjectAt(i, obj); - ++i; - ASSERT(i < obj_count); - // The second entry is used for arguments descriptor. - obj = ReadObject(); - } break; - case ConstantPoolTag::kInterfaceCall: { - elem = ReadObject(); - ASSERT(elem.IsFunction()); - // InterfaceCall constant occupies 2 entries. - // The first entry is used for interface target. - pool.SetTypeAt(i, ObjectPool::EntryType::kTaggedObject, - ObjectPool::Patchability::kNotPatchable); - pool.SetObjectAt(i, elem); - ++i; - ASSERT(i < obj_count); - // The second entry is used for arguments descriptor. - obj = ReadObject(); - } break; - case ConstantPoolTag::kInstantiatedInterfaceCall: { - elem = ReadObject(); - ASSERT(elem.IsFunction()); - // InstantiatedInterfaceCall constant occupies 3 entries: - // 1) Interface target. - pool.SetTypeAt(i, ObjectPool::EntryType::kTaggedObject, - ObjectPool::Patchability::kNotPatchable); - pool.SetObjectAt(i, elem); - ++i; - ASSERT(i < obj_count); - // 2) Arguments descriptor. - obj = ReadObject(); - pool.SetTypeAt(i, ObjectPool::EntryType::kTaggedObject, - ObjectPool::Patchability::kNotPatchable); - pool.SetObjectAt(i, obj); - ++i; - ASSERT(i < obj_count); - // 3) Static receiver type. - obj = ReadObject(); - } break; - case ConstantPoolTag::kDynamicCall: { - name ^= ReadObject(); - ASSERT(name.IsSymbol()); - // Do not mangle ==: - // * operator == takes an Object so it is either not checked or - // checked at the entry because the parameter is marked covariant, - // neither of those cases require a dynamic invocation forwarder - if (!Field::IsGetterName(name) && - (name.raw() != Symbols::EqualOperator().raw())) { - name = Function::CreateDynamicInvocationForwarderName(name); - } - // DynamicCall constant occupies 2 entries: selector and arguments - // descriptor. - pool.SetTypeAt(i, ObjectPool::EntryType::kTaggedObject, - ObjectPool::Patchability::kNotPatchable); - pool.SetObjectAt(i, name); - ++i; - ASSERT(i < obj_count); - // The second entry is used for arguments descriptor. - obj = ReadObject(); - } break; - case ConstantPoolTag::kDirectCallViaDynamicForwarder: { - // DirectCallViaDynamicForwarder constant occupies 2 entries. - // The first entry is used for target function. - obj = ReadObject(); - ASSERT(obj.IsFunction()); - name = Function::Cast(obj).name(); - name = Function::CreateDynamicInvocationForwarderName(name); - obj = Function::Cast(obj).GetDynamicInvocationForwarder(name); - - pool.SetTypeAt(i, ObjectPool::EntryType::kTaggedObject, - ObjectPool::Patchability::kNotPatchable); - pool.SetObjectAt(i, obj); - ++i; - ASSERT(i < obj_count); - // The second entry is used for arguments descriptor. - obj = ReadObject(); - } break; - default: - UNREACHABLE(); - } - pool.SetTypeAt(i, ObjectPool::EntryType::kTaggedObject, - ObjectPool::Patchability::kNotPatchable); - pool.SetObjectAt(i, obj); - } - - return obj_count - 1; -} - -BytecodePtr BytecodeReaderHelper::ReadBytecode(const ObjectPool& pool) { -#if defined(SUPPORT_TIMELINE) - TIMELINE_DURATION(Thread::Current(), CompilerVerbose, - "BytecodeReaderHelper::ReadBytecode"); -#endif // defined(SUPPORT_TIMELINE) - const intptr_t size = reader_.ReadUInt(); - const intptr_t offset = reader_.offset(); - - const uint8_t* data = reader_.BufferAt(offset); - reader_.set_offset(offset + size); - - // Create and return bytecode object. - return Bytecode::New(reinterpret_cast(data), size, offset, pool); -} - -void BytecodeReaderHelper::ReadExceptionsTable(const Bytecode& bytecode, - bool has_exceptions_table) { -#if defined(SUPPORT_TIMELINE) - TIMELINE_DURATION(Thread::Current(), CompilerVerbose, - "BytecodeReaderHelper::ReadExceptionsTable"); -#endif - - const intptr_t try_block_count = - has_exceptions_table ? reader_.ReadListLength() : 0; - if (try_block_count > 0) { - const ObjectPool& pool = ObjectPool::Handle(Z, bytecode.object_pool()); - AbstractType& handler_type = AbstractType::Handle(Z); - Array& handler_types = Array::Handle(Z); - DescriptorList* pc_descriptors_list = new (Z) DescriptorList(Z); - ExceptionHandlerList* exception_handlers_list = - new (Z) ExceptionHandlerList(); - - // Encoding of ExceptionsTable is described in - // pkg/vm/lib/bytecode/exceptions.dart. - for (intptr_t try_index = 0; try_index < try_block_count; try_index++) { - intptr_t outer_try_index_plus1 = reader_.ReadUInt(); - intptr_t outer_try_index = outer_try_index_plus1 - 1; - // PcDescriptors are expressed in terms of return addresses. - intptr_t start_pc = - KernelBytecode::BytecodePcToOffset(reader_.ReadUInt(), - /* is_return_address = */ true); - intptr_t end_pc = - KernelBytecode::BytecodePcToOffset(reader_.ReadUInt(), - /* is_return_address = */ true); - intptr_t handler_pc = - KernelBytecode::BytecodePcToOffset(reader_.ReadUInt(), - /* is_return_address = */ false); - uint8_t flags = reader_.ReadByte(); - const uint8_t kFlagNeedsStackTrace = 1 << 0; - const uint8_t kFlagIsSynthetic = 1 << 1; - const bool needs_stacktrace = (flags & kFlagNeedsStackTrace) != 0; - const bool is_generated = (flags & kFlagIsSynthetic) != 0; - intptr_t type_count = reader_.ReadListLength(); - ASSERT(type_count > 0); - handler_types = Array::New(type_count, Heap::kOld); - for (intptr_t i = 0; i < type_count; i++) { - intptr_t type_index = reader_.ReadUInt(); - ASSERT(type_index < pool.Length()); - handler_type ^= pool.ObjectAt(type_index); - handler_types.SetAt(i, handler_type); - } - pc_descriptors_list->AddDescriptor( - PcDescriptorsLayout::kOther, start_pc, DeoptId::kNone, - TokenPosition::kNoSource, try_index, - PcDescriptorsLayout::kInvalidYieldIndex); - pc_descriptors_list->AddDescriptor( - PcDescriptorsLayout::kOther, end_pc, DeoptId::kNone, - TokenPosition::kNoSource, try_index, - PcDescriptorsLayout::kInvalidYieldIndex); - - // The exception handler keeps a zone handle of the types array, rather - // than a raw pointer. Do not share the handle across iterations to avoid - // clobbering the array. - exception_handlers_list->AddHandler( - try_index, outer_try_index, handler_pc, is_generated, - Array::ZoneHandle(Z, handler_types.raw()), needs_stacktrace); - } - const PcDescriptors& descriptors = PcDescriptors::Handle( - Z, pc_descriptors_list->FinalizePcDescriptors(bytecode.PayloadStart())); - bytecode.set_pc_descriptors(descriptors); - const ExceptionHandlers& handlers = ExceptionHandlers::Handle( - Z, exception_handlers_list->FinalizeExceptionHandlers( - bytecode.PayloadStart())); - bytecode.set_exception_handlers(handlers); - } else { - bytecode.set_pc_descriptors(Object::empty_descriptors()); - bytecode.set_exception_handlers(Object::empty_exception_handlers()); - } -} - -void BytecodeReaderHelper::ReadSourcePositions(const Bytecode& bytecode, - bool has_source_positions) { - if (!has_source_positions) { - return; - } - - intptr_t offset = reader_.ReadUInt(); - bytecode.set_source_positions_binary_offset( - bytecode_component_->GetSourcePositionsOffset() + offset); -} - -void BytecodeReaderHelper::ReadLocalVariables(const Bytecode& bytecode, - bool has_local_variables) { - if (!has_local_variables) { - return; - } - - const intptr_t offset = reader_.ReadUInt(); - bytecode.set_local_variables_binary_offset( - bytecode_component_->GetLocalVariablesOffset() + offset); -} - -TypedDataPtr BytecodeReaderHelper::NativeEntry(const Function& function, - const String& external_name) { - MethodRecognizer::Kind kind = function.recognized_kind(); - // This list of recognized methods must be kept in sync with the list of - // methods handled specially by the NativeCall bytecode in the interpreter. - switch (kind) { - case MethodRecognizer::kObjectEquals: - case MethodRecognizer::kStringBaseLength: - case MethodRecognizer::kStringBaseIsEmpty: - case MethodRecognizer::kGrowableArrayLength: - case MethodRecognizer::kObjectArrayLength: - case MethodRecognizer::kImmutableArrayLength: - case MethodRecognizer::kTypedListLength: - case MethodRecognizer::kTypedListViewLength: - case MethodRecognizer::kByteDataViewLength: - case MethodRecognizer::kByteDataViewOffsetInBytes: - case MethodRecognizer::kTypedDataViewOffsetInBytes: - case MethodRecognizer::kByteDataViewTypedData: - case MethodRecognizer::kTypedDataViewTypedData: - case MethodRecognizer::kClassIDgetID: - case MethodRecognizer::kGrowableArrayCapacity: - case MethodRecognizer::kListFactory: - case MethodRecognizer::kObjectArrayAllocate: - case MethodRecognizer::kLinkedHashMap_getIndex: - case MethodRecognizer::kLinkedHashMap_setIndex: - case MethodRecognizer::kLinkedHashMap_getData: - case MethodRecognizer::kLinkedHashMap_setData: - case MethodRecognizer::kLinkedHashMap_getHashMask: - case MethodRecognizer::kLinkedHashMap_setHashMask: - case MethodRecognizer::kLinkedHashMap_getUsedData: - case MethodRecognizer::kLinkedHashMap_setUsedData: - case MethodRecognizer::kLinkedHashMap_getDeletedKeys: - case MethodRecognizer::kLinkedHashMap_setDeletedKeys: - case MethodRecognizer::kFfiAbi: -#define TYPED_DATA_FACTORY(clazz) \ - case MethodRecognizer::kTypedData_##clazz##_factory: - CLASS_LIST_TYPED_DATA(TYPED_DATA_FACTORY) -#undef TYPED_DATA_FACTORY - break; - case MethodRecognizer::kAsyncStackTraceHelper: - // If causal async stacks are disabled the interpreter.cc will handle this - // native call specially. - if (!FLAG_causal_async_stacks) { - break; - } - FALL_THROUGH; - default: - kind = MethodRecognizer::kUnknown; - } - NativeFunctionWrapper trampoline = NULL; - NativeFunction native_function = NULL; - intptr_t argc_tag = 0; - if (kind == MethodRecognizer::kUnknown) { - if (!FLAG_link_natives_lazily) { - const Class& cls = Class::Handle(Z, function.Owner()); - const Library& library = Library::Handle(Z, cls.library()); - Dart_NativeEntryResolver resolver = library.native_entry_resolver(); - const bool is_bootstrap_native = Bootstrap::IsBootstrapResolver(resolver); - const int num_params = - NativeArguments::ParameterCountForResolution(function); - bool is_auto_scope = true; - native_function = NativeEntry::ResolveNative(library, external_name, - num_params, &is_auto_scope); - if (native_function == nullptr) { - Report::MessageF(Report::kError, Script::Handle(function.script()), - function.token_pos(), Report::AtLocation, - "native function '%s' (%" Pd - " arguments) cannot be found", - external_name.ToCString(), function.NumParameters()); - } - if (is_bootstrap_native) { - trampoline = &NativeEntry::BootstrapNativeCallWrapper; - } else if (is_auto_scope) { - trampoline = &NativeEntry::AutoScopeNativeCallWrapper; - } else { - trampoline = &NativeEntry::NoScopeNativeCallWrapper; - } - } - argc_tag = NativeArguments::ComputeArgcTag(function); - } - return NativeEntryData::New(kind, trampoline, native_function, argc_tag); -} - -ArrayPtr BytecodeReaderHelper::ReadBytecodeComponent(intptr_t md_offset) { - ASSERT(Thread::Current()->IsMutatorThread()); - - AlternativeReadingScope alt(&reader_, md_offset); - - const intptr_t start_offset = reader_.offset(); - - intptr_t magic = reader_.ReadUInt32(); - if (magic != KernelBytecode::kMagicValue) { - FATAL1("Unexpected Dart bytecode magic %" Px, magic); - } - - const intptr_t version = reader_.ReadUInt32(); - if ((version < KernelBytecode::kMinSupportedBytecodeFormatVersion) || - (version > KernelBytecode::kMaxSupportedBytecodeFormatVersion)) { - FATAL3("Unsupported Dart bytecode format version %" Pd - ". " - "This version of Dart VM supports bytecode format versions from %" Pd - " to %" Pd ".", - version, KernelBytecode::kMinSupportedBytecodeFormatVersion, - KernelBytecode::kMaxSupportedBytecodeFormatVersion); - } - - reader_.ReadUInt32(); // Skip stringTable.numItems - const intptr_t string_table_offset = start_offset + reader_.ReadUInt32(); - - reader_.ReadUInt32(); // Skip objectTable.numItems - const intptr_t object_table_offset = start_offset + reader_.ReadUInt32(); - - reader_.ReadUInt32(); // Skip main.numItems - const intptr_t main_offset = start_offset + reader_.ReadUInt32(); - - const intptr_t num_libraries = reader_.ReadUInt32(); - const intptr_t library_index_offset = start_offset + reader_.ReadUInt32(); - - reader_.ReadUInt32(); // Skip libraries.numItems - const intptr_t libraries_offset = start_offset + reader_.ReadUInt32(); - - const intptr_t num_classes = reader_.ReadUInt32(); - const intptr_t classes_offset = start_offset + reader_.ReadUInt32(); - - reader_.ReadUInt32(); // Skip members.numItems - const intptr_t members_offset = start_offset + reader_.ReadUInt32(); - - const intptr_t num_codes = reader_.ReadUInt32(); - const intptr_t codes_offset = start_offset + reader_.ReadUInt32(); - - reader_.ReadUInt32(); // Skip sourcePositions.numItems - const intptr_t source_positions_offset = start_offset + reader_.ReadUInt32(); - - reader_.ReadUInt32(); // Skip sourceFiles.numItems - const intptr_t source_files_offset = start_offset + reader_.ReadUInt32(); - - reader_.ReadUInt32(); // Skip lineStarts.numItems - const intptr_t line_starts_offset = start_offset + reader_.ReadUInt32(); - - reader_.ReadUInt32(); // Skip localVariables.numItems - const intptr_t local_variables_offset = start_offset + reader_.ReadUInt32(); - - reader_.ReadUInt32(); // Skip annotations.numItems - const intptr_t annotations_offset = start_offset + reader_.ReadUInt32(); - - const intptr_t num_protected_names = reader_.ReadUInt32(); - const intptr_t protected_names_offset = start_offset + reader_.ReadUInt32(); - - // Read header of string table. - reader_.set_offset(string_table_offset); - const intptr_t num_one_byte_strings = reader_.ReadUInt32(); - const intptr_t num_two_byte_strings = reader_.ReadUInt32(); - const intptr_t strings_contents_offset = - reader_.offset() + (num_one_byte_strings + num_two_byte_strings) * 4; - - // Read header of object table. - reader_.set_offset(object_table_offset); - const intptr_t num_objects = reader_.ReadUInt(); - const intptr_t objects_size = reader_.ReadUInt(); - - // Skip over contents of objects. - const intptr_t objects_contents_offset = reader_.offset(); - const intptr_t object_offsets_offset = objects_contents_offset + objects_size; - reader_.set_offset(object_offsets_offset); - - auto& bytecode_component_array = Array::Handle( - Z, - BytecodeComponentData::New( - Z, version, num_objects, string_table_offset, strings_contents_offset, - object_offsets_offset, objects_contents_offset, main_offset, - num_libraries, library_index_offset, libraries_offset, num_classes, - classes_offset, members_offset, num_codes, codes_offset, - source_positions_offset, source_files_offset, line_starts_offset, - local_variables_offset, annotations_offset, Heap::kOld)); - - BytecodeComponentData bytecode_component(&bytecode_component_array); - - // Read object offsets. - Smi& offs = Smi::Handle(Z); - for (intptr_t i = 0; i < num_objects; ++i) { - offs = Smi::New(reader_.ReadUInt()); - bytecode_component.SetObject(i, offs); - } - - // Read protected names. - if (I->obfuscate() && (num_protected_names > 0)) { - bytecode_component_ = &bytecode_component; - - reader_.set_offset(protected_names_offset); - Obfuscator obfuscator(thread_, Object::null_string()); - auto& name = String::Handle(Z); - for (intptr_t i = 0; i < num_protected_names; ++i) { - name = ReadString(); - obfuscator.PreventRenaming(name); - } - - bytecode_component_ = nullptr; - } - - H.SetBytecodeComponent(bytecode_component_array); - - return bytecode_component_array.raw(); -} - -void BytecodeReaderHelper::ResetObjects() { - reader_.set_offset(bytecode_component_->GetObjectOffsetsOffset()); - const intptr_t num_objects = bytecode_component_->GetNumObjects(); - - // Read object offsets. - Smi& offs = Smi::Handle(Z); - for (intptr_t i = 0; i < num_objects; ++i) { - offs = Smi::New(reader_.ReadUInt()); - bytecode_component_->SetObject(i, offs); - } -} - -ObjectPtr BytecodeReaderHelper::ReadObject() { - uint32_t header = reader_.ReadUInt(); - if ((header & kReferenceBit) != 0) { - intptr_t index = header >> kIndexShift; - if (index == 0) { - return Object::null(); - } - ObjectPtr obj = bytecode_component_->GetObject(index); - if (obj->IsHeapObject()) { - return obj; - } - // Object is not loaded yet. - intptr_t offset = bytecode_component_->GetObjectsContentsOffset() + - Smi::Value(Smi::RawCast(obj)); - AlternativeReadingScope alt(&reader_, offset); - header = reader_.ReadUInt(); - - obj = ReadObjectContents(header); - ASSERT(obj->IsHeapObject()); - { - REUSABLE_OBJECT_HANDLESCOPE(thread_); - Object& obj_handle = thread_->ObjectHandle(); - obj_handle = obj; - bytecode_component_->SetObject(index, obj_handle); - } - return obj; - } - - return ReadObjectContents(header); -} - -StringPtr BytecodeReaderHelper::ConstructorName(const Class& cls, - const String& name) { - GrowableHandlePtrArray pieces(Z, 3); - pieces.Add(String::Handle(Z, cls.Name())); - pieces.Add(Symbols::Dot()); - pieces.Add(name); - return Symbols::FromConcatAll(thread_, pieces); -} - -ObjectPtr BytecodeReaderHelper::ReadObjectContents(uint32_t header) { - ASSERT(((header & kReferenceBit) == 0)); - - // Must be in sync with enum ObjectKind in - // pkg/vm/lib/bytecode/object_table.dart. - enum ObjectKind { - kInvalid, - kLibrary, - kClass, - kMember, - kClosure, - kUnused1, - kUnused2, - kUnused3, - kUnused4, - kName, - kTypeArguments, - kUnused5, - kConstObject, - kArgDesc, - kScript, - kType, - }; - - // Member flags, must be in sync with _MemberHandle constants in - // pkg/vm/lib/bytecode/object_table.dart. - const intptr_t kFlagIsField = kFlagBit0; - const intptr_t kFlagIsConstructor = kFlagBit1; - - // ArgDesc flags, must be in sync with _ArgDescHandle constants in - // pkg/vm/lib/bytecode/object_table.dart. - const int kFlagHasNamedArgs = kFlagBit0; - const int kFlagHasTypeArgs = kFlagBit1; - - // Script flags, must be in sync with _ScriptHandle constants in - // pkg/vm/lib/bytecode/object_table.dart. - const int kFlagHasSourceFile = kFlagBit0; - - // Name flags, must be in sync with _NameHandle constants in - // pkg/vm/lib/bytecode/object_table.dart. - const intptr_t kFlagIsPublic = kFlagBit0; - - const intptr_t kind = (header >> kKindShift) & kKindMask; - const intptr_t flags = header & kFlagsMask; - - switch (kind) { - case kInvalid: - UNREACHABLE(); - break; - case kLibrary: { - String& uri = String::CheckedHandle(Z, ReadObject()); - LibraryPtr library = Library::LookupLibrary(thread_, uri); - if (library == Library::null()) { - // We do not register expression evaluation libraries with the VM: - // The expression evaluation functions should be GC-able as soon as - // they are not reachable anymore and we never look them up by name. - if (uri.raw() == Symbols::EvalSourceUri().raw()) { - ASSERT(expression_evaluation_library_ != nullptr); - return expression_evaluation_library_->raw(); - } -#if !defined(PRODUCT) - ASSERT(Isolate::Current()->HasAttemptedReload()); - const String& msg = String::Handle( - Z, - String::NewFormatted("Unable to find library %s", uri.ToCString())); - Report::LongJump(LanguageError::Handle(Z, LanguageError::New(msg))); -#else - FATAL1("Unable to find library %s", uri.ToCString()); -#endif - } - return library; - } - case kClass: { - const Library& library = Library::CheckedHandle(Z, ReadObject()); - const String& class_name = String::CheckedHandle(Z, ReadObject()); - if (class_name.raw() == Symbols::Empty().raw()) { - NoSafepointScope no_safepoint_scope(thread_); - ClassPtr cls = library.toplevel_class(); - if (cls == Class::null()) { - FATAL1("Unable to find toplevel class %s", library.ToCString()); - } - return cls; - } - ClassPtr cls = library.LookupLocalClass(class_name); - if (cls == Class::null()) { - if (IsExpressionEvaluationLibrary(library)) { - return H.GetExpressionEvaluationRealClass(); - } -#if !defined(PRODUCT) - ASSERT(Isolate::Current()->HasAttemptedReload()); - const String& msg = String::Handle( - Z, - String::NewFormatted("Unable to find class %s in %s", - class_name.ToCString(), library.ToCString())); - Report::LongJump(LanguageError::Handle(Z, LanguageError::New(msg))); -#else - FATAL2("Unable to find class %s in %s", class_name.ToCString(), - library.ToCString()); -#endif - } - return cls; - } - case kMember: { - const Class& cls = Class::CheckedHandle(Z, ReadObject()); - String& name = String::CheckedHandle(Z, ReadObject()); - if ((flags & kFlagIsField) != 0) { - FieldPtr field = cls.LookupField(name); - if (field == Field::null()) { -#if !defined(PRODUCT) - ASSERT(Isolate::Current()->HasAttemptedReload()); - const String& msg = String::Handle( - Z, String::NewFormatted("Unable to find field %s in %s", - name.ToCString(), cls.ToCString())); - Report::LongJump(LanguageError::Handle(Z, LanguageError::New(msg))); -#else - FATAL2("Unable to find field %s in %s", name.ToCString(), - cls.ToCString()); -#endif - } - return field; - } else { - if ((flags & kFlagIsConstructor) != 0) { - name = ConstructorName(cls, name); - } - ASSERT(!name.IsNull() && name.IsSymbol()); - if (name.raw() == scoped_function_name_.raw() && - cls.raw() == scoped_function_class_.raw()) { - return scoped_function_.raw(); - } - FunctionPtr function = Function::null(); - if (cls.EnsureIsFinalized(thread_) == Error::null()) { - function = Resolver::ResolveFunction(Z, cls, name); - } - if (function == Function::null()) { - // When requesting a getter, also return method extractors. - if (Field::IsGetterName(name)) { - String& method_name = - String::Handle(Z, Field::NameFromGetter(name)); - function = Resolver::ResolveFunction(Z, cls, method_name); - if (function != Function::null()) { - function = Function::Handle(Z, function).GetMethodExtractor(name); - if (function != Function::null()) { - return function; - } - } - } -#if !defined(PRODUCT) - ASSERT(Isolate::Current()->HasAttemptedReload()); - const String& msg = String::Handle( - Z, String::NewFormatted("Unable to find function %s in %s", - name.ToCString(), cls.ToCString())); - Report::LongJump(LanguageError::Handle(Z, LanguageError::New(msg))); -#else - FATAL2("Unable to find function %s in %s", name.ToCString(), - cls.ToCString()); -#endif - } - return function; - } - } - case kClosure: { - ReadObject(); // Skip enclosing member. - const intptr_t closure_index = reader_.ReadUInt(); - return closures_->At(closure_index); - } - case kName: { - if ((flags & kFlagIsPublic) == 0) { - const Library& library = Library::CheckedHandle(Z, ReadObject()); - ASSERT(!library.IsNull()); - auto& name = String::Handle(Z, ReadString(/* is_canonical = */ false)); - name = library.PrivateName(name); - if (I->obfuscate()) { - const auto& library_key = String::Handle(Z, library.private_key()); - Obfuscator obfuscator(thread_, library_key); - return obfuscator.Rename(name); - } - return name.raw(); - } - if (I->obfuscate()) { - Obfuscator obfuscator(thread_, Object::null_string()); - const auto& name = String::Handle(Z, ReadString()); - return obfuscator.Rename(name); - } else { - return ReadString(); - } - } - case kTypeArguments: { - return ReadTypeArguments(); - } - case kConstObject: { - const intptr_t tag = flags / kFlagBit0; - return ReadConstObject(tag); - } - case kArgDesc: { - const intptr_t num_arguments = reader_.ReadUInt(); - const intptr_t num_type_args = - ((flags & kFlagHasTypeArgs) != 0) ? reader_.ReadUInt() : 0; - if ((flags & kFlagHasNamedArgs) == 0) { - return ArgumentsDescriptor::NewBoxed(num_type_args, num_arguments); - } else { - const intptr_t num_arg_names = reader_.ReadListLength(); - const Array& array = Array::Handle(Z, Array::New(num_arg_names)); - String& name = String::Handle(Z); - for (intptr_t i = 0; i < num_arg_names; ++i) { - name ^= ReadObject(); - array.SetAt(i, name); - } - return ArgumentsDescriptor::NewBoxed(num_type_args, num_arguments, - array); - } - } - case kScript: { - const String& uri = String::CheckedHandle(Z, ReadObject()); - Script& script = Script::Handle(Z); - if ((flags & kFlagHasSourceFile) != 0) { - // TODO(alexmarkov): read source and line starts only when needed. - script = - ReadSourceFile(uri, bytecode_component_->GetSourceFilesOffset() + - reader_.ReadUInt()); - } else { - script = Script::New(uri, Object::null_string()); - } - script.set_kernel_program_info(H.GetKernelProgramInfo()); - return script.raw(); - } - case kType: { - const intptr_t tag = (flags & kTagMask) / kFlagBit0; - const Nullability nullability = - Reader::ConvertNullability(static_cast( - (flags & kNullabilityMask) / kFlagBit4)); - return ReadType(tag, nullability); - } - default: - UNREACHABLE(); - } - - return Object::null(); -} - -ObjectPtr BytecodeReaderHelper::ReadConstObject(intptr_t tag) { - // Must be in sync with enum ConstTag in - // pkg/vm/lib/bytecode/object_table.dart. - enum ConstTag { - kInvalid, - kInstance, - kInt, - kDouble, - kList, - kTearOff, - kBool, - kSymbol, - kTearOffInstantiation, - kString, - }; - - switch (tag) { - case kInvalid: - UNREACHABLE(); - break; - case kInstance: { - const Type& type = Type::CheckedHandle(Z, ReadObject()); - const Class& cls = Class::Handle(Z, type.type_class()); - const Instance& obj = Instance::Handle(Z, Instance::New(cls, Heap::kOld)); - if (type.arguments() != TypeArguments::null()) { - const TypeArguments& type_args = - TypeArguments::Handle(Z, type.arguments()); - obj.SetTypeArguments(type_args); - } - const intptr_t num_fields = reader_.ReadUInt(); - Field& field = Field::Handle(Z); - Object& value = Object::Handle(Z); - for (intptr_t i = 0; i < num_fields; ++i) { - field ^= ReadObject(); - value = ReadObject(); - obj.SetField(field, value); - } - return H.Canonicalize(obj); - } - case kInt: { - const int64_t value = reader_.ReadSLEB128AsInt64(); - if (Smi::IsValid(value)) { - return Smi::New(static_cast(value)); - } - const Integer& obj = Integer::Handle(Z, Integer::New(value, Heap::kOld)); - return H.Canonicalize(obj); - } - case kDouble: { - const int64_t bits = reader_.ReadSLEB128AsInt64(); - double value = bit_cast(bits); - const Double& obj = Double::Handle(Z, Double::New(value, Heap::kOld)); - return H.Canonicalize(obj); - } - case kList: { - const AbstractType& elem_type = - AbstractType::CheckedHandle(Z, ReadObject()); - const intptr_t length = reader_.ReadUInt(); - const Array& array = Array::Handle(Z, Array::New(length, elem_type)); - Object& value = Object::Handle(Z); - for (intptr_t i = 0; i < length; ++i) { - value = ReadObject(); - array.SetAt(i, value); - } - array.MakeImmutable(); - return H.Canonicalize(array); - } - case kTearOff: { - Object& obj = Object::Handle(Z, ReadObject()); - ASSERT(obj.IsFunction()); - obj = Function::Cast(obj).ImplicitClosureFunction(); - ASSERT(obj.IsFunction()); - obj = Function::Cast(obj).ImplicitStaticClosure(); - ASSERT(obj.IsInstance()); - return H.Canonicalize(Instance::Cast(obj)); - } - case kBool: { - bool is_true = reader_.ReadByte() != 0; - return is_true ? Bool::True().raw() : Bool::False().raw(); - } - case kSymbol: { - const String& name = String::CheckedHandle(Z, ReadObject()); - ASSERT(name.IsSymbol()); - const Library& library = Library::Handle(Z, Library::InternalLibrary()); - ASSERT(!library.IsNull()); - const Class& cls = - Class::Handle(Z, library.LookupClass(Symbols::Symbol())); - ASSERT(!cls.IsNull()); - const Field& field = Field::Handle( - Z, cls.LookupInstanceFieldAllowPrivate(Symbols::_name())); - ASSERT(!field.IsNull()); - const Instance& obj = Instance::Handle(Z, Instance::New(cls, Heap::kOld)); - obj.SetField(field, name); - return H.Canonicalize(obj); - } - case kTearOffInstantiation: { - Closure& closure = Closure::CheckedHandle(Z, ReadObject()); - const TypeArguments& type_args = - TypeArguments::CheckedHandle(Z, ReadObject()); - closure = Closure::New( - TypeArguments::Handle(Z, closure.instantiator_type_arguments()), - TypeArguments::Handle(Z, closure.function_type_arguments()), - type_args, Function::Handle(Z, closure.function()), - Context::Handle(Z, closure.context()), Heap::kOld); - return H.Canonicalize(closure); - } - case kString: - return ReadString(); - default: - UNREACHABLE(); - } - return Object::null(); -} - -ObjectPtr BytecodeReaderHelper::ReadType(intptr_t tag, - Nullability nullability) { - // Must be in sync with enum TypeTag in - // pkg/vm/lib/bytecode/object_table.dart. - enum TypeTag { - kInvalid, - kDynamic, - kVoid, - kSimpleType, - kTypeParameter, - kGenericType, - kRecursiveGenericType, - kRecursiveTypeRef, - kFunctionType, - kNever, - }; - - // FunctionType flags, must be in sync with _FunctionTypeHandle constants in - // pkg/vm/lib/bytecode/object_table.dart. - const int kFlagHasOptionalPositionalParams = 1 << 0; - const int kFlagHasOptionalNamedParams = 1 << 1; - const int kFlagHasTypeParams = 1 << 2; - - switch (tag) { - case kInvalid: - UNREACHABLE(); - break; - case kDynamic: - return AbstractType::dynamic_type().raw(); - case kVoid: - return AbstractType::void_type().raw(); - case kNever: - return Type::Handle(Z, Type::NeverType()) - .ToNullability(nullability, Heap::kOld); - case kSimpleType: { - const Class& cls = Class::CheckedHandle(Z, ReadObject()); - if (!cls.is_declaration_loaded()) { - LoadReferencedClass(cls); - } - const Type& type = Type::Handle(Z, cls.DeclarationType()); - return type.ToNullability(nullability, Heap::kOld); - } - case kTypeParameter: { - Object& parent = Object::Handle(Z, ReadObject()); - const intptr_t index_in_parent = reader_.ReadUInt(); - TypeArguments& type_parameters = TypeArguments::Handle(Z); - if (parent.IsClass()) { - type_parameters = Class::Cast(parent).type_parameters(); - } else if (parent.IsFunction()) { - if (Function::Cast(parent).IsFactory()) { - // For factory constructors VM uses type parameters of a class - // instead of constructor's type parameters. - parent = Function::Cast(parent).Owner(); - type_parameters = Class::Cast(parent).type_parameters(); - } else { - type_parameters = Function::Cast(parent).type_parameters(); - } - } else if (parent.IsNull()) { - ASSERT(function_type_type_parameters_ != nullptr); - type_parameters = function_type_type_parameters_->raw(); - } else { - UNREACHABLE(); - } - TypeParameter& type_parameter = TypeParameter::Handle(Z); - type_parameter ^= type_parameters.TypeAt(index_in_parent); - if (type_parameter.bound() == AbstractType::null()) { - AbstractType& derived = AbstractType::Handle( - Z, type_parameter.ToNullability(nullability, Heap::kOld)); - active_class_->RecordDerivedTypeParameter(Z, type_parameter, - TypeParameter::Cast(derived)); - return derived.raw(); - } - return type_parameter.ToNullability(nullability, Heap::kOld); - } - case kGenericType: { - const Class& cls = Class::CheckedHandle(Z, ReadObject()); - if (!cls.is_declaration_loaded()) { - LoadReferencedClass(cls); - } - const TypeArguments& type_arguments = - TypeArguments::CheckedHandle(Z, ReadObject()); - const Type& type = - Type::Handle(Z, Type::New(cls, type_arguments, - TokenPosition::kNoSource, nullability)); - type.SetIsFinalized(); - return type.Canonicalize(thread_, nullptr); - } - case kRecursiveGenericType: { - const intptr_t id = reader_.ReadUInt(); - const Class& cls = Class::CheckedHandle(Z, ReadObject()); - if (!cls.is_declaration_loaded()) { - LoadReferencedClass(cls); - } - const auto saved_pending_recursive_types = pending_recursive_types_; - if (id == 0) { - pending_recursive_types_ = &GrowableObjectArray::Handle( - Z, GrowableObjectArray::New(Heap::kOld)); - } - ASSERT(id == pending_recursive_types_->Length()); - const auto& type_ref = - TypeRef::Handle(Z, TypeRef::New(AbstractType::null_abstract_type())); - pending_recursive_types_->Add(type_ref); - - reading_type_arguments_of_recursive_type_ = true; - const TypeArguments& type_arguments = - TypeArguments::CheckedHandle(Z, ReadObject()); - reading_type_arguments_of_recursive_type_ = false; - - ASSERT(id == pending_recursive_types_->Length() - 1); - ASSERT(pending_recursive_types_->At(id) == type_ref.raw()); - pending_recursive_types_->SetLength(id); - pending_recursive_types_ = saved_pending_recursive_types; - - Type& type = - Type::Handle(Z, Type::New(cls, type_arguments, - TokenPosition::kNoSource, nullability)); - type_ref.set_type(type); - type.SetIsFinalized(); - if (id != 0) { - // Do not canonicalize non-root recursive types - // as not all TypeRef objects are filled up at this point. - return type.raw(); - } - return type.Canonicalize(thread_, nullptr); - } - case kRecursiveTypeRef: { - const intptr_t id = reader_.ReadUInt(); - ASSERT(pending_recursive_types_ != nullptr); - ASSERT(pending_recursive_types_->Length() >= id); - return pending_recursive_types_->At(id); - } - case kFunctionType: { - const intptr_t flags = reader_.ReadUInt(); - Function& signature_function = Function::ZoneHandle( - Z, Function::NewSignatureFunction(*active_class_->klass, - active_class_->enclosing != NULL - ? *active_class_->enclosing - : Function::null_function(), - TokenPosition::kNoSource)); - - // This scope is needed to set active_class_->enclosing_ which is used to - // assign parent function for function types. - ActiveEnclosingFunctionScope active_enclosing_function( - active_class_, &signature_function); - - // TODO(alexmarkov): skip type finalization - return ReadFunctionSignature( - signature_function, (flags & kFlagHasOptionalPositionalParams) != 0, - (flags & kFlagHasOptionalNamedParams) != 0, - (flags & kFlagHasTypeParams) != 0, - /* has_positional_param_names = */ false, - /* has_parameter_flags */ false, nullability); - } - default: - UNREACHABLE(); - } - return Object::null(); -} - -StringPtr BytecodeReaderHelper::ReadString(bool is_canonical) { - const int kFlagTwoByteString = 1; - const int kHeaderFields = 2; - const int kUInt32Size = 4; - - uint32_t ref = reader_.ReadUInt(); - const bool isOneByteString = (ref & kFlagTwoByteString) == 0; - intptr_t index = ref >> 1; - - if (!isOneByteString) { - const uint32_t num_one_byte_strings = - reader_.ReadUInt32At(bytecode_component_->GetStringsHeaderOffset()); - index += num_one_byte_strings; - } - - AlternativeReadingScope alt(&reader_, - bytecode_component_->GetStringsHeaderOffset() + - (kHeaderFields + index - 1) * kUInt32Size); - intptr_t start_offs = reader_.ReadUInt32(); - intptr_t end_offs = reader_.ReadUInt32(); - if (index == 0) { - // For the 0-th string we read a header field instead of end offset of - // the previous string. - start_offs = 0; - } - - // Bytecode strings reside in ExternalTypedData which is not movable by GC, - // so it is OK to take a direct pointer to string characters even if - // symbol allocation triggers GC. - const uint8_t* data = reader_.BufferAt( - bytecode_component_->GetStringsContentsOffset() + start_offs); - - if (is_canonical) { - if (isOneByteString) { - return Symbols::FromLatin1(thread_, data, end_offs - start_offs); - } else { - return Symbols::FromUTF16(thread_, - reinterpret_cast(data), - (end_offs - start_offs) >> 1); - } - } else { - if (isOneByteString) { - return String::FromLatin1(data, end_offs - start_offs, Heap::kOld); - } else { - return String::FromUTF16(reinterpret_cast(data), - (end_offs - start_offs) >> 1, Heap::kOld); - } - } -} - -ScriptPtr BytecodeReaderHelper::ReadSourceFile(const String& uri, - intptr_t offset) { - // SourceFile flags, must be in sync with SourceFile constants in - // pkg/vm/lib/bytecode/declarations.dart. - const int kHasLineStartsFlag = 1 << 0; - const int kHasSourceFlag = 1 << 1; - - AlternativeReadingScope alt(&reader_, offset); - - const intptr_t flags = reader_.ReadUInt(); - const String& import_uri = String::CheckedHandle(Z, ReadObject()); - - TypedData& line_starts = TypedData::Handle(Z); - if ((flags & kHasLineStartsFlag) != 0) { - // TODO(alexmarkov): read line starts only when needed. - const intptr_t line_starts_offset = - bytecode_component_->GetLineStartsOffset() + reader_.ReadUInt(); - - AlternativeReadingScope alt(&reader_, line_starts_offset); - - const intptr_t num_line_starts = reader_.ReadUInt(); - line_starts = reader_.ReadLineStartsData(num_line_starts); - } - - String& source = String::Handle(Z); - if ((flags & kHasSourceFlag) != 0) { - source = ReadString(/* is_canonical = */ false); - } - - const Script& script = - Script::Handle(Z, Script::New(import_uri, uri, source)); - script.set_line_starts(line_starts); - - if (source.IsNull() && line_starts.IsNull()) { - // This script provides a uri only, but no source or line_starts array. - // This could be a reference to a Script in another kernel binary. - // Make an attempt to find source and line starts when needed. - script.SetLazyLookupSourceAndLineStarts(true); - } - - return script.raw(); -} - -TypeArgumentsPtr BytecodeReaderHelper::ReadTypeArguments() { - const bool is_recursive = reading_type_arguments_of_recursive_type_; - reading_type_arguments_of_recursive_type_ = false; - const intptr_t length = reader_.ReadUInt(); - TypeArguments& type_arguments = - TypeArguments::ZoneHandle(Z, TypeArguments::New(length)); - AbstractType& type = AbstractType::Handle(Z); - for (intptr_t i = 0; i < length; ++i) { - type ^= ReadObject(); - type_arguments.SetTypeAt(i, type); - } - if (is_recursive) { - // Avoid canonicalization of type arguments of recursive type - // as not all TypeRef objects are filled up at this point. - // Type arguments will be canoncialized when the root recursive - // type is canonicalized. - ASSERT(pending_recursive_types_ != nullptr); - return type_arguments.raw(); - } - return type_arguments.Canonicalize(thread_, nullptr); -} - -void BytecodeReaderHelper::ReadAttributes(const Object& key) { - ASSERT(key.IsFunction() || key.IsField()); - const auto& value = Object::Handle(Z, ReadObject()); - - Array& attributes = - Array::Handle(Z, I->object_store()->bytecode_attributes()); - if (attributes.IsNull()) { - attributes = HashTables::New(16, Heap::kOld); - } - BytecodeAttributesMap map(attributes.raw()); - bool present = map.UpdateOrInsert(key, value); - ASSERT(!present); - I->object_store()->set_bytecode_attributes(map.Release()); - - if (key.IsField()) { - const Field& field = Field::Cast(key); - const auto& inferred_type_attr = - Array::CheckedHandle(Z, BytecodeReader::GetBytecodeAttribute( - key, Symbols::vm_inferred_type_metadata())); - - if (!inferred_type_attr.IsNull() && - (InferredTypeBytecodeAttribute::GetPCAt(inferred_type_attr, 0) == - InferredTypeBytecodeAttribute::kFieldTypePC)) { - const InferredTypeMetadata type = - InferredTypeBytecodeAttribute::GetInferredTypeAt( - Z, inferred_type_attr, 0); - if (!type.IsTrivial()) { - field.set_guarded_cid(type.cid); - field.set_is_nullable(type.IsNullable()); - field.set_guarded_list_length(Field::kNoFixedLength); - } - } - } -} - -void BytecodeReaderHelper::ReadMembers(const Class& cls, bool discard_fields) { - ASSERT(Thread::Current()->IsMutatorThread()); - ASSERT(cls.is_type_finalized()); - ASSERT(!cls.is_loaded()); - - const intptr_t num_functions = reader_.ReadUInt(); - functions_ = &Array::Handle(Z, Array::New(num_functions, Heap::kOld)); - function_index_ = 0; - - ReadFieldDeclarations(cls, discard_fields); - ReadFunctionDeclarations(cls); - - cls.set_is_loaded(true); -} - -void BytecodeReaderHelper::ReadFieldDeclarations(const Class& cls, - bool discard_fields) { - // Field flags, must be in sync with FieldDeclaration constants in - // pkg/vm/lib/bytecode/declarations.dart. - const int kHasNontrivialInitializerFlag = 1 << 0; - const int kHasGetterFlag = 1 << 1; - const int kHasSetterFlag = 1 << 2; - const int kIsReflectableFlag = 1 << 3; - const int kIsStaticFlag = 1 << 4; - const int kIsConstFlag = 1 << 5; - const int kIsFinalFlag = 1 << 6; - const int kIsCovariantFlag = 1 << 7; - const int kIsGenericCovariantImplFlag = 1 << 8; - const int kHasSourcePositionsFlag = 1 << 9; - const int kHasAnnotationsFlag = 1 << 10; - const int kHasPragmaFlag = 1 << 11; - const int kHasCustomScriptFlag = 1 << 12; - const int kHasInitializerCodeFlag = 1 << 13; - const int kHasAttributesFlag = 1 << 14; - const int kIsLateFlag = 1 << 15; - const int kIsExtensionMemberFlag = 1 << 16; - const int kHasInitializerFlag = 1 << 17; - - const int num_fields = reader_.ReadListLength(); - if ((num_fields == 0) && !cls.is_enum_class()) { - return; - } - const Array& fields = Array::Handle( - Z, Array::New(num_fields + (cls.is_enum_class() ? 1 : 0), Heap::kOld)); - String& name = String::Handle(Z); - Object& script_class = Object::Handle(Z); - AbstractType& type = AbstractType::Handle(Z); - Field& field = Field::Handle(Z); - Instance& value = Instance::Handle(Z); - Function& function = Function::Handle(Z); - - for (intptr_t i = 0; i < num_fields; ++i) { - intptr_t flags = reader_.ReadUInt(); - - const bool is_static = (flags & kIsStaticFlag) != 0; - const bool is_final = (flags & kIsFinalFlag) != 0; - const bool is_const = (flags & kIsConstFlag) != 0; - const bool is_late = (flags & kIsLateFlag) != 0; - const bool has_nontrivial_initializer = - (flags & kHasNontrivialInitializerFlag) != 0; - const bool has_pragma = (flags & kHasPragmaFlag) != 0; - const bool is_extension_member = (flags & kIsExtensionMemberFlag) != 0; - const bool has_initializer = (flags & kHasInitializerFlag) != 0; - - name ^= ReadObject(); - type ^= ReadObject(); - - if ((flags & kHasCustomScriptFlag) != 0) { - Script& script = Script::CheckedHandle(Z, ReadObject()); - script_class = GetPatchClass(cls, script); - } else { - script_class = cls.raw(); - } - - TokenPosition position = TokenPosition::kNoSource; - TokenPosition end_position = TokenPosition::kNoSource; - if ((flags & kHasSourcePositionsFlag) != 0) { - position = reader_.ReadPosition(); - end_position = reader_.ReadPosition(); - } - - field = Field::New(name, is_static, is_final, is_const, - (flags & kIsReflectableFlag) != 0, is_late, script_class, - type, position, end_position); - - field.set_is_declared_in_bytecode(true); - field.set_has_pragma(has_pragma); - field.set_is_covariant((flags & kIsCovariantFlag) != 0); - field.set_is_generic_covariant_impl((flags & kIsGenericCovariantImplFlag) != - 0); - field.set_has_nontrivial_initializer(has_nontrivial_initializer); - field.set_is_extension_member(is_extension_member); - field.set_has_initializer(has_initializer); - - if (!has_nontrivial_initializer) { - value ^= ReadObject(); - if (is_static) { - if (field.is_late() && !has_initializer) { - field.SetStaticValue(Object::sentinel(), true); - } else { - field.SetStaticValue(value, true); - } - } else { - field.set_saved_initial_value(value); - // Null-initialized instance fields are tracked separately for each - // constructor (see handling of kHasNullableFieldsFlag). - if (!value.IsNull()) { - // Note: optimizer relies on DoubleInitialized bit in its - // field-unboxing heuristics. - // See JitCallSpecializer::VisitStoreInstanceField for more details. - field.RecordStore(value); - if (value.IsDouble()) { - field.set_is_double_initialized(true); - } - } - } - } - - if ((flags & kHasInitializerCodeFlag) != 0) { - const intptr_t code_offset = reader_.ReadUInt(); - field.set_bytecode_offset(code_offset + - bytecode_component_->GetCodesOffset()); - if (is_static) { - field.SetStaticValue(Object::sentinel(), true); - } - } - - if ((flags & kHasGetterFlag) != 0) { - name ^= ReadObject(); - function = Function::New(name, - is_static ? FunctionLayout::kImplicitStaticGetter - : FunctionLayout::kImplicitGetter, - is_static, is_const, - false, // is_abstract - false, // is_external - false, // is_native - script_class, position); - function.set_end_token_pos(end_position); - function.set_result_type(type); - function.set_is_debuggable(false); - function.set_accessor_field(field); - function.set_is_declared_in_bytecode(true); - function.set_is_extension_member(is_extension_member); - if (is_const && has_nontrivial_initializer) { - function.set_bytecode_offset(field.bytecode_offset()); - } - H.SetupFieldAccessorFunction(cls, function, type); - functions_->SetAt(function_index_++, function); - } - - if ((flags & kHasSetterFlag) != 0) { - ASSERT(is_late || ((!is_static) && (!is_final))); - ASSERT(!is_const); - name ^= ReadObject(); - function = Function::New(name, FunctionLayout::kImplicitSetter, is_static, - false, // is_const - false, // is_abstract - false, // is_external - false, // is_native - script_class, position); - function.set_end_token_pos(end_position); - function.set_result_type(Object::void_type()); - function.set_is_debuggable(false); - function.set_accessor_field(field); - function.set_is_declared_in_bytecode(true); - function.set_is_extension_member(is_extension_member); - H.SetupFieldAccessorFunction(cls, function, type); - functions_->SetAt(function_index_++, function); - } - - if ((flags & kHasAnnotationsFlag) != 0) { - intptr_t annotations_offset = - reader_.ReadUInt() + bytecode_component_->GetAnnotationsOffset(); - ASSERT(annotations_offset > 0); - - if (FLAG_enable_mirrors || has_pragma) { - Library& library = Library::Handle(Z, cls.library()); - library.AddFieldMetadata(field, TokenPosition::kNoSource, 0, - annotations_offset); - if (has_pragma) { - // TODO(alexmarkov): read annotations right away using - // annotations_offset. - NoOOBMessageScope no_msg_scope(thread_); - NoReloadScope no_reload_scope(thread_->isolate(), thread_); - library.GetMetadata(field); - } - } - } - - if ((flags & kHasAttributesFlag) != 0) { - ReadAttributes(field); - } - - fields.SetAt(i, field); - } - - if (cls.is_enum_class()) { - // Add static field 'const _deleted_enum_sentinel'. - field = Field::New(Symbols::_DeletedEnumSentinel(), - /* is_static = */ true, - /* is_final = */ true, - /* is_const = */ true, - /* is_reflectable = */ false, - /* is_late = */ false, cls, Object::dynamic_type(), - TokenPosition::kNoSource, TokenPosition::kNoSource); - - fields.SetAt(num_fields, field); - } - - if (!discard_fields) { - cls.SetFields(fields); - } - - if (cls.IsTopLevel()) { - const Library& library = Library::Handle(Z, cls.library()); - for (intptr_t i = 0, n = fields.Length(); i < n; ++i) { - field ^= fields.At(i); - name = field.name(); - library.AddObject(field, name); - } - } -} - -PatchClassPtr BytecodeReaderHelper::GetPatchClass(const Class& cls, - const Script& script) { - if (patch_class_ != nullptr && patch_class_->patched_class() == cls.raw() && - patch_class_->script() == script.raw()) { - return patch_class_->raw(); - } - if (patch_class_ == nullptr) { - patch_class_ = &PatchClass::Handle(Z); - } - *patch_class_ = PatchClass::New(cls, script); - return patch_class_->raw(); -} - -void BytecodeReaderHelper::ReadFunctionDeclarations(const Class& cls) { - // Function flags, must be in sync with FunctionDeclaration constants in - // pkg/vm/lib/bytecode/declarations.dart. - const int kIsConstructorFlag = 1 << 0; - const int kIsGetterFlag = 1 << 1; - const int kIsSetterFlag = 1 << 2; - const int kIsFactoryFlag = 1 << 3; - const int kIsStaticFlag = 1 << 4; - const int kIsAbstractFlag = 1 << 5; - const int kIsConstFlag = 1 << 6; - const int kHasOptionalPositionalParamsFlag = 1 << 7; - const int kHasOptionalNamedParamsFlag = 1 << 8; - const int kHasTypeParamsFlag = 1 << 9; - const int kIsReflectableFlag = 1 << 10; - const int kIsDebuggableFlag = 1 << 11; - const int kIsAsyncFlag = 1 << 12; - const int kIsAsyncStarFlag = 1 << 13; - const int kIsSyncStarFlag = 1 << 14; - // const int kIsForwardingStubFlag = 1 << 15; - const int kIsNoSuchMethodForwarderFlag = 1 << 16; - const int kIsNativeFlag = 1 << 17; - const int kIsExternalFlag = 1 << 18; - const int kHasSourcePositionsFlag = 1 << 19; - const int kHasAnnotationsFlag = 1 << 20; - const int kHasPragmaFlag = 1 << 21; - const int kHasCustomScriptFlag = 1 << 22; - const int kHasAttributesFlag = 1 << 23; - const int kIsExtensionMemberFlag = 1 << 24; - const int kHasParameterFlagsFlag = 1 << 25; - - const intptr_t num_functions = reader_.ReadListLength(); - ASSERT(function_index_ + num_functions == functions_->Length()); - - if (function_index_ + num_functions == 0) { - return; - } - - String& name = String::Handle(Z); - Object& script_class = Object::Handle(Z); - Function& function = Function::Handle(Z); - Array& parameter_types = Array::Handle(Z); - AbstractType& type = AbstractType::Handle(Z); - - name = cls.ScrubbedName(); - const bool is_async_await_completer_owner = - Symbols::_AsyncAwaitCompleter().Equals(name); - - for (intptr_t i = 0; i < num_functions; ++i) { - intptr_t flags = reader_.ReadUInt(); - - const bool is_static = (flags & kIsStaticFlag) != 0; - const bool is_factory = (flags & kIsFactoryFlag) != 0; - const bool is_native = (flags & kIsNativeFlag) != 0; - const bool has_pragma = (flags & kHasPragmaFlag) != 0; - const bool is_extension_member = (flags & kIsExtensionMemberFlag) != 0; - - name ^= ReadObject(); - - if ((flags & kHasCustomScriptFlag) != 0) { - Script& script = Script::CheckedHandle(Z, ReadObject()); - script_class = GetPatchClass(cls, script); - } else { - script_class = cls.raw(); - } - - TokenPosition position = TokenPosition::kNoSource; - TokenPosition end_position = TokenPosition::kNoSource; - if ((flags & kHasSourcePositionsFlag) != 0) { - position = reader_.ReadPosition(); - end_position = reader_.ReadPosition(); - } - - FunctionLayout::Kind kind = FunctionLayout::kRegularFunction; - if ((flags & kIsGetterFlag) != 0) { - kind = FunctionLayout::kGetterFunction; - } else if ((flags & kIsSetterFlag) != 0) { - kind = FunctionLayout::kSetterFunction; - } else if ((flags & (kIsConstructorFlag | kIsFactoryFlag)) != 0) { - kind = FunctionLayout::kConstructor; - name = ConstructorName(cls, name); - } - - function = Function::New(name, kind, is_static, (flags & kIsConstFlag) != 0, - (flags & kIsAbstractFlag) != 0, - (flags & kIsExternalFlag) != 0, is_native, - script_class, position); - - const bool is_expression_evaluation = - (name.raw() == Symbols::DebugProcedureName().raw()); - - // Declare function scope as types (type parameters) in function - // signature may back-reference to the function being declared. - // At this moment, owner class is not fully loaded yet and it won't be - // able to serve function lookup requests. - FunctionScope function_scope(this, function, name, cls); - - function.set_is_declared_in_bytecode(true); - function.set_has_pragma(has_pragma); - function.set_end_token_pos(end_position); - function.set_is_synthetic((flags & kIsNoSuchMethodForwarderFlag) != 0); - function.set_is_reflectable((flags & kIsReflectableFlag) != 0); - function.set_is_debuggable((flags & kIsDebuggableFlag) != 0); - function.set_is_extension_member(is_extension_member); - - // _AsyncAwaitCompleter.start should be made non-visible in stack traces, - // since it is an implementation detail of our await/async desugaring. - if (is_async_await_completer_owner && - Symbols::_AsyncAwaitStart().Equals(name)) { - function.set_is_visible(!FLAG_causal_async_stacks && - !FLAG_lazy_async_stacks); - } - - if ((flags & kIsSyncStarFlag) != 0) { - function.set_modifier(FunctionLayout::kSyncGen); - function.set_is_visible(!FLAG_causal_async_stacks && - !FLAG_lazy_async_stacks); - } else if ((flags & kIsAsyncFlag) != 0) { - function.set_modifier(FunctionLayout::kAsync); - function.set_is_inlinable(!FLAG_causal_async_stacks && - !FLAG_lazy_async_stacks); - function.set_is_visible(!FLAG_causal_async_stacks && - !FLAG_lazy_async_stacks); - } else if ((flags & kIsAsyncStarFlag) != 0) { - function.set_modifier(FunctionLayout::kAsyncGen); - function.set_is_inlinable(!FLAG_causal_async_stacks && - !FLAG_lazy_async_stacks); - function.set_is_visible(!FLAG_causal_async_stacks && - !FLAG_lazy_async_stacks); - } - - if ((flags & kHasTypeParamsFlag) != 0) { - ReadTypeParametersDeclaration(Class::Handle(Z), function); - } - - const intptr_t num_implicit_params = (!is_static || is_factory) ? 1 : 0; - const intptr_t num_params = num_implicit_params + reader_.ReadUInt(); - - intptr_t num_required_params = num_params; - if ((flags & (kHasOptionalPositionalParamsFlag | - kHasOptionalNamedParamsFlag)) != 0) { - num_required_params = num_implicit_params + reader_.ReadUInt(); - } - - function.set_num_fixed_parameters(num_required_params); - function.SetNumOptionalParameters( - num_params - num_required_params, - (flags & kHasOptionalNamedParamsFlag) == 0); - - parameter_types = Array::New(num_params, Heap::kOld); - function.set_parameter_types(parameter_types); - function.CreateNameArrayIncludingFlags(Heap::kOld); - - intptr_t param_index = 0; - if (!is_static) { - if (is_expression_evaluation) { - // Do not reference enclosing class as expression evaluation - // method logically belongs to another (real) class. - // Enclosing class is not registered and doesn't have - // a valid cid, so it can't be used in a type. - function.SetParameterTypeAt(param_index, AbstractType::dynamic_type()); - } else { - function.SetParameterTypeAt(param_index, H.GetDeclarationType(cls)); - } - function.SetParameterNameAt(param_index, Symbols::This()); - ++param_index; - } else if (is_factory) { - function.SetParameterTypeAt(param_index, AbstractType::dynamic_type()); - function.SetParameterNameAt(param_index, - Symbols::TypeArgumentsParameter()); - ++param_index; - } - - for (; param_index < num_params; ++param_index) { - name ^= ReadObject(); - function.SetParameterNameAt(param_index, name); - type ^= ReadObject(); - function.SetParameterTypeAt(param_index, type); - } - - if ((flags & kHasParameterFlagsFlag) != 0) { - const intptr_t length = reader_.ReadUInt(); - const intptr_t offset = function.NumImplicitParameters(); - for (intptr_t i = 0; i < length; i++) { - const intptr_t param_flags = reader_.ReadUInt(); - if ((param_flags & Parameter::kIsRequiredFlag) != 0) { - RELEASE_ASSERT(function.HasOptionalNamedParameters()); - RELEASE_ASSERT(i + offset >= function.num_fixed_parameters()); - function.SetIsRequiredAt(i + offset); - } - } - } - function.TruncateUnusedParameterFlags(); - - type ^= ReadObject(); - function.set_result_type(type); - - if (is_native) { - name ^= ReadObject(); - function.set_native_name(name); - } - - if ((flags & kIsAbstractFlag) == 0) { - const intptr_t code_offset = reader_.ReadUInt(); - function.set_bytecode_offset(code_offset + - bytecode_component_->GetCodesOffset()); - } - - if ((flags & kHasAnnotationsFlag) != 0) { - const intptr_t annotations_offset = - reader_.ReadUInt() + bytecode_component_->GetAnnotationsOffset(); - ASSERT(annotations_offset > 0); - - if (FLAG_enable_mirrors || has_pragma) { - Library& library = Library::Handle(Z, cls.library()); - library.AddFunctionMetadata(function, TokenPosition::kNoSource, 0, - annotations_offset); - - if (has_pragma) { - if (H.constants().IsNull() && - library.raw() == Library::CoreLibrary()) { - // Bootstrapping, need to postpone evaluation of pragma annotations - // as classes are not fully loaded/finalized yet. - const auto& pragma_funcs = GrowableObjectArray::Handle( - Z, H.EnsurePotentialPragmaFunctions()); - pragma_funcs.Add(function); - } else { - // TODO(alexmarkov): read annotations right away using - // annotations_offset. - Thread* thread = H.thread(); - NoOOBMessageScope no_msg_scope(thread); - NoReloadScope no_reload_scope(thread->isolate(), thread); - library.GetMetadata(function); - } - } - } - } - - if ((flags & kHasAttributesFlag) != 0) { - ASSERT(!is_expression_evaluation); - ReadAttributes(function); - } - - if (is_expression_evaluation) { - H.SetExpressionEvaluationFunction(function); - // Read bytecode of expression evaluation function eagerly, - // while expression_evaluation_library_ and FunctionScope - // are still set, as its constant pool may reference back to a library - // or a function which are not registered and cannot be looked up. - ASSERT(!function.is_abstract()); - ASSERT(function.bytecode_offset() != 0); - // Replace class of the function in scope as we're going to look for - // expression evaluation function in a real class. - if (!cls.IsTopLevel()) { - scoped_function_class_ = H.GetExpressionEvaluationRealClass(); - } - CompilerState compiler_state(thread_, FLAG_precompiled_mode); - ReadCode(function, function.bytecode_offset()); - } - - functions_->SetAt(function_index_++, function); - } - - { - Thread* thread = Thread::Current(); - SafepointWriteRwLocker ml(thread, thread->isolate_group()->program_lock()); - cls.SetFunctions(*functions_); - } - - if (cls.IsTopLevel()) { - const Library& library = Library::Handle(Z, cls.library()); - for (intptr_t i = 0, n = functions_->Length(); i < n; ++i) { - function ^= functions_->At(i); - name = function.name(); - library.AddObject(function, name); - } - } - - functions_ = nullptr; -} - -void BytecodeReaderHelper::LoadReferencedClass(const Class& cls) { - ASSERT(!cls.is_declaration_loaded()); - - if (!cls.is_declared_in_bytecode()) { - cls.EnsureDeclarationLoaded(); - return; - } - - const auto& script = Script::Handle(Z, cls.script()); - if (H.GetKernelProgramInfo().raw() != script.kernel_program_info()) { - // Class comes from a different binary. - cls.EnsureDeclarationLoaded(); - return; - } - - // We can reuse current BytecodeReaderHelper. - ActiveClassScope active_class_scope(active_class_, &cls); - AlternativeReadingScope alt(&reader_, cls.bytecode_offset()); - ReadClassDeclaration(cls); -} - -void BytecodeReaderHelper::ReadClassDeclaration(const Class& cls) { - // Class flags, must be in sync with ClassDeclaration constants in - // pkg/vm/lib/bytecode/declarations.dart. - const int kIsAbstractFlag = 1 << 0; - const int kIsEnumFlag = 1 << 1; - const int kHasTypeParamsFlag = 1 << 2; - const int kHasTypeArgumentsFlag = 1 << 3; - const int kIsTransformedMixinApplicationFlag = 1 << 4; - const int kHasSourcePositionsFlag = 1 << 5; - const int kHasAnnotationsFlag = 1 << 6; - const int kHasPragmaFlag = 1 << 7; - - // Class is allocated when reading library declaration in - // BytecodeReaderHelper::ReadLibraryDeclaration. - // Its cid is set in Class::New / Isolate::RegisterClass / - // ClassTable::Register, unless it was loaded for expression evaluation. - ASSERT(cls.is_declared_in_bytecode()); - ASSERT(!cls.is_declaration_loaded() || loading_native_wrappers_library_); - - const intptr_t flags = reader_.ReadUInt(); - const bool has_pragma = (flags & kHasPragmaFlag) != 0; - - // Set early to enable access to type_parameters(). - // TODO(alexmarkov): revise early stamping of native wrapper classes - // as loaded. - if (!cls.is_declaration_loaded()) { - cls.set_is_declaration_loaded(); - } - - const auto& script = Script::CheckedHandle(Z, ReadObject()); - cls.set_script(script); - - TokenPosition position = TokenPosition::kNoSource; - TokenPosition end_position = TokenPosition::kNoSource; - if ((flags & kHasSourcePositionsFlag) != 0) { - position = reader_.ReadPosition(); - end_position = reader_.ReadPosition(); - cls.set_token_pos(position); - cls.set_end_token_pos(end_position); - } - - cls.set_has_pragma(has_pragma); - - if ((flags & kIsAbstractFlag) != 0) { - cls.set_is_abstract(); - } - if ((flags & kIsEnumFlag) != 0) { - cls.set_is_enum_class(); - } - if ((flags & kIsTransformedMixinApplicationFlag) != 0) { - cls.set_is_transformed_mixin_application(); - } - - intptr_t num_type_arguments = 0; - if ((flags & kHasTypeArgumentsFlag) != 0) { - num_type_arguments = reader_.ReadUInt(); - } - cls.set_num_type_arguments(num_type_arguments); - - if ((flags & kHasTypeParamsFlag) != 0) { - ReadTypeParametersDeclaration(cls, Function::null_function()); - } - - auto& type = AbstractType::CheckedHandle(Z, ReadObject()); - cls.set_super_type(type); - - const intptr_t num_interfaces = reader_.ReadUInt(); - if (num_interfaces > 0) { - const auto& interfaces = - Array::Handle(Z, Array::New(num_interfaces, Heap::kOld)); - for (intptr_t i = 0; i < num_interfaces; ++i) { - type ^= ReadObject(); - interfaces.SetAt(i, type); - } - cls.set_interfaces(interfaces); - } - - if ((flags & kHasAnnotationsFlag) != 0) { - intptr_t annotations_offset = - reader_.ReadUInt() + bytecode_component_->GetAnnotationsOffset(); - ASSERT(annotations_offset > 0); - - if (FLAG_enable_mirrors || has_pragma) { - const auto& library = Library::Handle(Z, cls.library()); - if (cls.IsTopLevel()) { - ASSERT(!has_pragma); - library.AddLibraryMetadata(cls, TokenPosition::kNoSource, 0, - annotations_offset); - } else { - const auto& top_level_class = - Class::Handle(Z, library.toplevel_class()); - - library.AddClassMetadata(cls, top_level_class, TokenPosition::kNoSource, - 0, annotations_offset); - } - } - } - - const intptr_t members_offset = reader_.ReadUInt(); - cls.set_bytecode_offset(members_offset + - bytecode_component_->GetMembersOffset()); - - // All types are finalized if loading from bytecode. - // TODO(alexmarkov): revise early stamping of native wrapper classes - // as type-finalized. - if (!cls.is_type_finalized()) { - cls.set_is_type_finalized(); - } - - // Avoid registering expression evaluation class in a hierarchy, as - // it doesn't have cid and shouldn't be found when enumerating subclasses. - if (expression_evaluation_library_ == nullptr) { - // TODO(alexmarkov): move this to class finalization. - ClassFinalizer::RegisterClassInHierarchy(Z, cls); - } -} - -void BytecodeReaderHelper::ReadLibraryDeclaration(const Library& library, - bool lookup_classes) { - // Library flags, must be in sync with LibraryDeclaration constants in - // pkg/vm/lib/bytecode/declarations.dart. - const int kUsesDartMirrorsFlag = 1 << 0; - const int kUsesDartFfiFlag = 1 << 1; - const int kHasExtensionsFlag = 1 << 2; - const int kIsNonNullableByDefaultFlag = 1 << 3; - - ASSERT(library.is_declared_in_bytecode()); - ASSERT(!library.Loaded()); - ASSERT(library.toplevel_class() == Object::null()); - - // TODO(alexmarkov): fill in library.used_scripts. - - const intptr_t flags = reader_.ReadUInt(); - if (((flags & kUsesDartMirrorsFlag) != 0) && !FLAG_enable_mirrors) { - H.ReportError( - "import of dart:mirrors is not supported in the current Dart runtime"); - } - if (((flags & kUsesDartFfiFlag) != 0) && !Api::IsFfiEnabled()) { - H.ReportError( - "import of dart:ffi is not supported in the current Dart runtime"); - } - - auto& name = String::CheckedHandle(Z, ReadObject()); - library.SetName(name); - - const auto& script = Script::CheckedHandle(Z, ReadObject()); - - if ((flags & kHasExtensionsFlag) != 0) { - const intptr_t num_extensions = reader_.ReadUInt(); - auto& import_namespace = Namespace::Handle(Z); - auto& native_library = Library::Handle(Z); - for (intptr_t i = 0; i < num_extensions; ++i) { - name ^= ReadObject(); - ASSERT(name.StartsWith(Symbols::DartExtensionScheme())); - - // Create a dummy library and add it as an import to the current library. - // Actual loading occurs in KernelLoader::LoadNativeExtensionLibraries(). - // This also allows later to discover and reload this native extension, - // e.g. when running from an app-jit snapshot. - // See Loader::ReloadNativeExtensions(...) which relies on - // Dart_GetImportsOfScheme('dart-ext'). - native_library = Library::New(name); - import_namespace = Namespace::New(native_library, Array::null_array(), - Array::null_array()); - library.AddImport(import_namespace); - } - H.AddPotentialExtensionLibrary(library); - } - - if ((flags & kIsNonNullableByDefaultFlag) != 0) { - library.set_is_nnbd(true); - } - - // The bootstrapper will take care of creating the native wrapper classes, - // but we will add the synthetic constructors to them here. - if (name.raw() == - Symbols::Symbol(Symbols::kDartNativeWrappersLibNameId).raw()) { - ASSERT(library.LoadInProgress()); - loading_native_wrappers_library_ = true; - } else { - loading_native_wrappers_library_ = false; - library.SetLoadInProgress(); - } - - const bool register_class = !IsExpressionEvaluationLibrary(library); - - const intptr_t num_classes = reader_.ReadUInt(); - ASSERT(num_classes > 0); - auto& cls = Class::Handle(Z); - - for (intptr_t i = 0; i < num_classes; ++i) { - name ^= ReadObject(); - const intptr_t class_offset = - bytecode_component_->GetClassesOffset() + reader_.ReadUInt(); - - if (i == 0) { - ASSERT(name.raw() == Symbols::Empty().raw()); - cls = Class::New(library, Symbols::TopLevel(), script, - TokenPosition::kNoSource, register_class); - library.set_toplevel_class(cls); - } else { - if (lookup_classes) { - cls = library.LookupLocalClass(name); - } - if (lookup_classes && !cls.IsNull()) { - ASSERT(!cls.is_declaration_loaded() || - loading_native_wrappers_library_); - cls.set_script(script); - } else { - cls = Class::New(library, name, script, TokenPosition::kNoSource, - register_class); - if (register_class) { - library.AddClass(cls); - } - } - } - - cls.set_is_declared_in_bytecode(true); - cls.set_bytecode_offset(class_offset); - - if (loading_native_wrappers_library_ || !register_class) { - AlternativeReadingScope alt(&reader_, class_offset); - ReadClassDeclaration(cls); - ActiveClassScope active_class_scope(active_class_, &cls); - AlternativeReadingScope alt2(&reader_, cls.bytecode_offset()); - ReadMembers(cls, /* discard_fields = */ false); - } - } - - ASSERT(!library.Loaded()); - library.SetLoaded(); - - loading_native_wrappers_library_ = false; -} - -void BytecodeReaderHelper::ReadLibraryDeclarations(intptr_t num_libraries) { - auto& library = Library::Handle(Z); - auto& uri = String::Handle(Z); - - for (intptr_t i = 0; i < num_libraries; ++i) { - uri ^= ReadObject(); - const intptr_t library_offset = - bytecode_component_->GetLibrariesOffset() + reader_.ReadUInt(); - - if (!FLAG_precompiled_mode && !I->should_load_vmservice()) { - if (uri.raw() == Symbols::DartVMServiceIO().raw()) { - continue; - } - } - - bool lookup_classes = true; - library = Library::LookupLibrary(thread_, uri); - if (library.IsNull()) { - lookup_classes = false; - library = Library::New(uri); - - if (uri.raw() == Symbols::EvalSourceUri().raw()) { - ASSERT(expression_evaluation_library_ == nullptr); - expression_evaluation_library_ = &Library::Handle(Z, library.raw()); - } else { - library.Register(thread_); - } - } - - if (library.Loaded()) { - continue; - } - - library.set_is_declared_in_bytecode(true); - library.set_bytecode_offset(library_offset); - - AlternativeReadingScope alt(&reader_, library_offset); - ReadLibraryDeclaration(library, lookup_classes); - } -} - -void BytecodeReaderHelper::FindAndReadSpecificLibrary(const Library& library, - intptr_t num_libraries) { - auto& uri = String::Handle(Z); - for (intptr_t i = 0; i < num_libraries; ++i) { - uri ^= ReadObject(); - const intptr_t library_offset = - bytecode_component_->GetLibrariesOffset() + reader_.ReadUInt(); - - if (uri.raw() == library.url()) { - library.set_is_declared_in_bytecode(true); - library.set_bytecode_offset(library_offset); - - AlternativeReadingScope alt(&reader_, library_offset); - ReadLibraryDeclaration(library, /* lookup_classes = */ true); - return; - } - } -} - -void BytecodeReaderHelper::FindModifiedLibrariesForHotReload( - BitVector* modified_libs, - intptr_t num_libraries) { - auto& uri = String::Handle(Z); - auto& lib = Library::Handle(Z); - for (intptr_t i = 0; i < num_libraries; ++i) { - uri ^= ReadObject(); - reader_.ReadUInt(); // Skip offset. - - lib = Library::LookupLibrary(thread_, uri); - if (!lib.IsNull() && !lib.is_dart_scheme()) { - // This is a library that already exists so mark it as being modified. - modified_libs->Add(lib.index()); - } - } -} - -void BytecodeReaderHelper::ReadParameterCovariance( - const Function& function, - BitVector* is_covariant, - BitVector* is_generic_covariant_impl) { - ASSERT(function.is_declared_in_bytecode()); - - const intptr_t num_params = function.NumParameters(); - ASSERT(is_covariant->length() == num_params); - ASSERT(is_generic_covariant_impl->length() == num_params); - - AlternativeReadingScope alt(&reader_, function.bytecode_offset()); - - const intptr_t code_flags = reader_.ReadUInt(); - if ((code_flags & Code::kHasParameterFlagsFlag) != 0) { - const intptr_t num_explicit_params = reader_.ReadUInt(); - ASSERT(num_params == - function.NumImplicitParameters() + num_explicit_params); - - for (intptr_t i = function.NumImplicitParameters(); i < num_params; ++i) { - const intptr_t flags = reader_.ReadUInt(); - - if ((flags & Parameter::kIsCovariantFlag) != 0) { - is_covariant->Add(i); - } - if ((flags & Parameter::kIsGenericCovariantImplFlag) != 0) { - is_generic_covariant_impl->Add(i); - } - } - } -} - -ObjectPtr BytecodeReaderHelper::BuildParameterDescriptor( - const Function& function) { - ASSERT(function.is_declared_in_bytecode()); - - Object& result = Object::Handle(Z); - if (!function.HasBytecode()) { - result = BytecodeReader::ReadFunctionBytecode(Thread::Current(), function); - if (result.IsError()) { - return result.raw(); - } - } - - const intptr_t num_params = function.NumParameters(); - const intptr_t num_implicit_params = function.NumImplicitParameters(); - const intptr_t num_explicit_params = num_params - num_implicit_params; - const Array& descriptor = Array::Handle( - Z, Array::New(num_explicit_params * Parser::kParameterEntrySize)); - - // 1. Find isFinal in the Code declaration. - bool found_final = false; - if (!function.is_abstract()) { - AlternativeReadingScope alt(&reader_, function.bytecode_offset()); - const intptr_t code_flags = reader_.ReadUInt(); - - if ((code_flags & Code::kHasParameterFlagsFlag) != 0) { - const intptr_t num_explicit_params_written = reader_.ReadUInt(); - ASSERT(num_explicit_params == num_explicit_params_written); - for (intptr_t i = 0; i < num_explicit_params; ++i) { - const intptr_t flags = reader_.ReadUInt(); - descriptor.SetAt( - i * Parser::kParameterEntrySize + Parser::kParameterIsFinalOffset, - Bool::Get((flags & Parameter::kIsFinalFlag) != 0)); - } - found_final = true; - } - } - if (!found_final) { - for (intptr_t i = 0; i < num_explicit_params; ++i) { - descriptor.SetAt( - i * Parser::kParameterEntrySize + Parser::kParameterIsFinalOffset, - Bool::Get(false)); - } - } - - // 2. Find metadata implicitly after the function declaration's metadata. - const Class& klass = Class::Handle(Z, function.Owner()); - const Library& library = Library::Handle(Z, klass.library()); - const Object& metadata = Object::Handle( - Z, library.GetExtendedMetadata(function, num_explicit_params)); - if (metadata.IsError()) { - return metadata.raw(); - } - if (Array::Cast(metadata).Length() != 0) { - for (intptr_t i = 0; i < num_explicit_params; i++) { - result = Array::Cast(metadata).At(i); - descriptor.SetAt( - i * Parser::kParameterEntrySize + Parser::kParameterMetadataOffset, - result); - } - } - - // 3. Find the defaultValues in the EntryOptional sequence. - if (!function.is_abstract()) { - const Bytecode& bytecode = Bytecode::Handle(Z, function.bytecode()); - ASSERT(!bytecode.IsNull()); - const ObjectPool& constants = ObjectPool::Handle(Z, bytecode.object_pool()); - ASSERT(!constants.IsNull()); - const KBCInstr* instr = - reinterpret_cast(bytecode.PayloadStart()); - if (KernelBytecode::IsEntryOptionalOpcode(instr)) { - // Note that number of fixed parameters may not match 'A' operand of - // EntryOptional bytecode as [function] could be an implicit closure - // function with an extra implicit argument, while bytecode corresponds - // to a static function without any implicit arguments. - const intptr_t num_fixed_params = function.num_fixed_parameters(); - const intptr_t num_opt_pos_params = KernelBytecode::DecodeB(instr); - const intptr_t num_opt_named_params = KernelBytecode::DecodeC(instr); - instr = KernelBytecode::Next(instr); - ASSERT(num_opt_pos_params == function.NumOptionalPositionalParameters()); - ASSERT(num_opt_named_params == function.NumOptionalNamedParameters()); - ASSERT((num_opt_pos_params == 0) || (num_opt_named_params == 0)); - - for (intptr_t i = 0; i < num_opt_pos_params; i++) { - const KBCInstr* load_value_instr = instr; - instr = KernelBytecode::Next(instr); - ASSERT(KernelBytecode::IsLoadConstantOpcode(load_value_instr)); - result = constants.ObjectAt(KernelBytecode::DecodeE(load_value_instr)); - descriptor.SetAt((num_fixed_params - num_implicit_params + i) * - Parser::kParameterEntrySize + - Parser::kParameterDefaultValueOffset, - result); - } - for (intptr_t i = 0; i < num_opt_named_params; i++) { - const KBCInstr* load_name_instr = instr; - const KBCInstr* load_value_instr = - KernelBytecode::Next(load_name_instr); - instr = KernelBytecode::Next(load_value_instr); - ASSERT(KernelBytecode::IsLoadConstantOpcode(load_name_instr)); - result = constants.ObjectAt(KernelBytecode::DecodeE(load_name_instr)); - intptr_t param_index; - for (param_index = num_fixed_params; param_index < num_params; - param_index++) { - if (function.ParameterNameAt(param_index) == result.raw()) { - break; - } - } - ASSERT(param_index < num_params); - ASSERT(KernelBytecode::IsLoadConstantOpcode(load_value_instr)); - result = constants.ObjectAt(KernelBytecode::DecodeE(load_value_instr)); - descriptor.SetAt( - (param_index - num_implicit_params) * Parser::kParameterEntrySize + - Parser::kParameterDefaultValueOffset, - result); - } - } - } - - return descriptor.raw(); -} - -void BytecodeReaderHelper::ParseBytecodeFunction( - ParsedFunction* parsed_function, - const Function& function) { - // Handle function kinds which don't have a user-defined body first. - switch (function.kind()) { - case FunctionLayout::kImplicitClosureFunction: - ParseForwarderFunction(parsed_function, function, - Function::Handle(Z, function.parent_function())); - return; - case FunctionLayout::kDynamicInvocationForwarder: - ParseForwarderFunction(parsed_function, function, - Function::Handle(Z, function.ForwardingTarget())); - return; - case FunctionLayout::kImplicitGetter: - case FunctionLayout::kImplicitSetter: - case FunctionLayout::kMethodExtractor: - BytecodeScopeBuilder(parsed_function).BuildScopes(); - return; - case FunctionLayout::kImplicitStaticGetter: { - if (IsStaticFieldGetterGeneratedAsInitializer(function, Z)) { - break; - } else { - BytecodeScopeBuilder(parsed_function).BuildScopes(); - return; - } - } - case FunctionLayout::kRegularFunction: - case FunctionLayout::kGetterFunction: - case FunctionLayout::kSetterFunction: - case FunctionLayout::kClosureFunction: - case FunctionLayout::kConstructor: - case FunctionLayout::kFieldInitializer: - break; - case FunctionLayout::kNoSuchMethodDispatcher: - case FunctionLayout::kInvokeFieldDispatcher: - case FunctionLayout::kSignatureFunction: - case FunctionLayout::kIrregexpFunction: - case FunctionLayout::kFfiTrampoline: - UNREACHABLE(); - break; - } - - // We only reach here if function has a bytecode body. Make sure it is - // loaded and collect information about covariant parameters. - - if (!function.HasBytecode()) { - ReadCode(function, function.bytecode_offset()); - ASSERT(function.HasBytecode()); - } - - // TODO(alexmarkov): simplify access to covariant / generic_covariant_impl - // flags of parameters so we won't need to read them separately. - if (!parsed_function->HasCovariantParametersInfo()) { - const intptr_t num_params = function.NumParameters(); - BitVector* covariant_parameters = new (Z) BitVector(Z, num_params); - BitVector* generic_covariant_impl_parameters = - new (Z) BitVector(Z, num_params); - ReadParameterCovariance(function, covariant_parameters, - generic_covariant_impl_parameters); - parsed_function->SetCovariantParameters(covariant_parameters); - parsed_function->SetGenericCovariantImplParameters( - generic_covariant_impl_parameters); - } -} - -void BytecodeReaderHelper::ParseForwarderFunction( - ParsedFunction* parsed_function, - const Function& function, - const Function& target) { - ASSERT(function.IsImplicitClosureFunction() || - function.IsDynamicInvocationForwarder()); - - ASSERT(target.is_declared_in_bytecode()); - - if (function.IsDynamicInvocationForwarder() && - target.IsImplicitSetterFunction()) { - BytecodeScopeBuilder(parsed_function).BuildScopes(); - return; - } - - if (!target.HasBytecode()) { - ReadCode(target, target.bytecode_offset()); - } - - BytecodeScopeBuilder(parsed_function).BuildScopes(); - - const auto& target_bytecode = Bytecode::Handle(Z, target.bytecode()); - const auto& obj_pool = ObjectPool::Handle(Z, target_bytecode.object_pool()); - - AlternativeReadingScope alt(&reader_, target.bytecode_offset()); - - const intptr_t flags = reader_.ReadUInt(); - const bool has_parameter_flags = (flags & Code::kHasParameterFlagsFlag) != 0; - const bool has_forwarding_stub_target = - (flags & Code::kHasForwardingStubTargetFlag) != 0; - const bool has_default_function_type_args = - (flags & Code::kHasDefaultFunctionTypeArgsFlag) != 0; - const auto proc_attrs = kernel::ProcedureAttributesOf(target, Z); - // TODO(alexmarkov): fix building of flow graph for implicit closures so - // it would include missing checks and remove 'proc_attrs.has_tearoff_uses' - // from this condition. - const bool body_has_generic_covariant_impl_type_checks = - proc_attrs.has_non_this_uses || proc_attrs.has_tearoff_uses; - - if (has_parameter_flags) { - const intptr_t num_params = reader_.ReadUInt(); - const intptr_t num_implicit_params = function.NumImplicitParameters(); - for (intptr_t i = 0; i < num_params; ++i) { - const intptr_t flags = reader_.ReadUInt(); - - bool is_covariant = (flags & Parameter::kIsCovariantFlag) != 0; - bool is_generic_covariant_impl = - (flags & Parameter::kIsGenericCovariantImplFlag) != 0; - - LocalVariable* variable = - parsed_function->ParameterVariable(num_implicit_params + i); - - if (is_covariant) { - variable->set_is_explicit_covariant_parameter(); - } - - const bool checked_in_method_body = - is_covariant || (is_generic_covariant_impl && - body_has_generic_covariant_impl_type_checks); - - if (checked_in_method_body) { - variable->set_type_check_mode(LocalVariable::kSkipTypeCheck); - } else { - ASSERT(variable->type_check_mode() == LocalVariable::kDoTypeCheck); - } - } - } - - if (has_forwarding_stub_target) { - const intptr_t cp_index = reader_.ReadUInt(); - const auto& forwarding_stub_target = - Function::CheckedZoneHandle(Z, obj_pool.ObjectAt(cp_index)); - parsed_function->MarkForwardingStub(&forwarding_stub_target); - } - - if (has_default_function_type_args) { - ASSERT(function.IsGeneric()); - const intptr_t cp_index = reader_.ReadUInt(); - const auto& type_args = - TypeArguments::CheckedHandle(Z, obj_pool.ObjectAt(cp_index)); - // In bytecode mode, all type parameters are created with a default - // argument of dynamic, so only need to update if not the all-dynamic TAV. - if (!type_args.IsNull()) { - auto& type_params = TypeArguments::Handle(Z, function.type_parameters()); - ASSERT_EQUAL(type_params.Length(), type_args.Length()); - auto& param = TypeParameter::Handle(Z); - auto& type = AbstractType::Handle(Z); - for (intptr_t i = 0; i < type_params.Length(); i++) { - param ^= type_params.TypeAt(i); - type = type_args.TypeAt(i); - param.set_default_argument(type); - } - function.UpdateCachedDefaultTypeArguments(thread_); - } - } - - if (function.HasOptionalParameters()) { - const KBCInstr* raw_bytecode = - reinterpret_cast(target_bytecode.PayloadStart()); - const KBCInstr* entry = raw_bytecode; - raw_bytecode = KernelBytecode::Next(raw_bytecode); - ASSERT(KernelBytecode::IsEntryOptionalOpcode(entry)); - ASSERT(KernelBytecode::DecodeB(entry) == - function.NumOptionalPositionalParameters()); - ASSERT(KernelBytecode::DecodeC(entry) == - function.NumOptionalNamedParameters()); - - const intptr_t num_opt_params = function.NumOptionalParameters(); - ZoneGrowableArray* default_values = - new (Z) ZoneGrowableArray(Z, num_opt_params); - - if (function.HasOptionalPositionalParameters()) { - for (intptr_t i = 0, n = function.NumOptionalPositionalParameters(); - i < n; ++i) { - const KBCInstr* load = raw_bytecode; - raw_bytecode = KernelBytecode::Next(raw_bytecode); - ASSERT(KernelBytecode::IsLoadConstantOpcode(load)); - const auto& value = Instance::CheckedZoneHandle( - Z, obj_pool.ObjectAt(KernelBytecode::DecodeE(load))); - default_values->Add(&value); - } - } else { - const intptr_t num_fixed_params = function.num_fixed_parameters(); - auto& param_name = String::Handle(Z); - default_values->EnsureLength(num_opt_params, nullptr); - for (intptr_t i = 0; i < num_opt_params; ++i) { - const KBCInstr* load_name = raw_bytecode; - const KBCInstr* load_value = KernelBytecode::Next(load_name); - raw_bytecode = KernelBytecode::Next(load_value); - ASSERT(KernelBytecode::IsLoadConstantOpcode(load_name)); - ASSERT(KernelBytecode::IsLoadConstantOpcode(load_value)); - param_name ^= obj_pool.ObjectAt(KernelBytecode::DecodeE(load_name)); - const auto& value = Instance::CheckedZoneHandle( - Z, obj_pool.ObjectAt(KernelBytecode::DecodeE(load_value))); - - const intptr_t num_params = function.NumParameters(); - intptr_t param_index = num_fixed_params; - for (; param_index < num_params; ++param_index) { - if (function.ParameterNameAt(param_index) == param_name.raw()) { - break; - } - } - ASSERT(param_index < num_params); - ASSERT(default_values->At(param_index - num_fixed_params) == nullptr); - (*default_values)[param_index - num_fixed_params] = &value; - } - } - - parsed_function->set_default_parameter_values(default_values); - } -} - -LibraryPtr BytecodeReaderHelper::ReadMain() { - return Library::RawCast(ReadObject()); -} - -intptr_t BytecodeComponentData::GetVersion() const { - return Smi::Value(Smi::RawCast(data_.At(kVersion))); -} - -intptr_t BytecodeComponentData::GetStringsHeaderOffset() const { - return Smi::Value(Smi::RawCast(data_.At(kStringsHeaderOffset))); -} - -intptr_t BytecodeComponentData::GetStringsContentsOffset() const { - return Smi::Value(Smi::RawCast(data_.At(kStringsContentsOffset))); -} - -intptr_t BytecodeComponentData::GetObjectOffsetsOffset() const { - return Smi::Value(Smi::RawCast(data_.At(kObjectOffsetsOffset))); -} - -intptr_t BytecodeComponentData::GetNumObjects() const { - return Smi::Value(Smi::RawCast(data_.At(kNumObjects))); -} - -intptr_t BytecodeComponentData::GetObjectsContentsOffset() const { - return Smi::Value(Smi::RawCast(data_.At(kObjectsContentsOffset))); -} - -intptr_t BytecodeComponentData::GetMainOffset() const { - return Smi::Value(Smi::RawCast(data_.At(kMainOffset))); -} - -intptr_t BytecodeComponentData::GetNumLibraries() const { - return Smi::Value(Smi::RawCast(data_.At(kNumLibraries))); -} - -intptr_t BytecodeComponentData::GetLibraryIndexOffset() const { - return Smi::Value(Smi::RawCast(data_.At(kLibraryIndexOffset))); -} - -intptr_t BytecodeComponentData::GetLibrariesOffset() const { - return Smi::Value(Smi::RawCast(data_.At(kLibrariesOffset))); -} - -intptr_t BytecodeComponentData::GetNumClasses() const { - return Smi::Value(Smi::RawCast(data_.At(kNumClasses))); -} - -intptr_t BytecodeComponentData::GetClassesOffset() const { - return Smi::Value(Smi::RawCast(data_.At(kClassesOffset))); -} - -intptr_t BytecodeComponentData::GetMembersOffset() const { - return Smi::Value(Smi::RawCast(data_.At(kMembersOffset))); -} - -intptr_t BytecodeComponentData::GetNumCodes() const { - return Smi::Value(Smi::RawCast(data_.At(kNumCodes))); -} - -intptr_t BytecodeComponentData::GetCodesOffset() const { - return Smi::Value(Smi::RawCast(data_.At(kCodesOffset))); -} - -intptr_t BytecodeComponentData::GetSourcePositionsOffset() const { - return Smi::Value(Smi::RawCast(data_.At(kSourcePositionsOffset))); -} - -intptr_t BytecodeComponentData::GetSourceFilesOffset() const { - return Smi::Value(Smi::RawCast(data_.At(kSourceFilesOffset))); -} - -intptr_t BytecodeComponentData::GetLineStartsOffset() const { - return Smi::Value(Smi::RawCast(data_.At(kLineStartsOffset))); -} - -intptr_t BytecodeComponentData::GetLocalVariablesOffset() const { - return Smi::Value(Smi::RawCast(data_.At(kLocalVariablesOffset))); -} - -intptr_t BytecodeComponentData::GetAnnotationsOffset() const { - return Smi::Value(Smi::RawCast(data_.At(kAnnotationsOffset))); -} - -void BytecodeComponentData::SetObject(intptr_t index, const Object& obj) const { - data_.SetAt(kNumFields + index, obj); -} - -ObjectPtr BytecodeComponentData::GetObject(intptr_t index) const { - return data_.At(kNumFields + index); -} - -ArrayPtr BytecodeComponentData::New(Zone* zone, - intptr_t version, - intptr_t num_objects, - intptr_t strings_header_offset, - intptr_t strings_contents_offset, - intptr_t object_offsets_offset, - intptr_t objects_contents_offset, - intptr_t main_offset, - intptr_t num_libraries, - intptr_t library_index_offset, - intptr_t libraries_offset, - intptr_t num_classes, - intptr_t classes_offset, - intptr_t members_offset, - intptr_t num_codes, - intptr_t codes_offset, - intptr_t source_positions_offset, - intptr_t source_files_offset, - intptr_t line_starts_offset, - intptr_t local_variables_offset, - intptr_t annotations_offset, - Heap::Space space) { - const Array& data = - Array::Handle(zone, Array::New(kNumFields + num_objects, space)); - Smi& smi_handle = Smi::Handle(zone); - - smi_handle = Smi::New(version); - data.SetAt(kVersion, smi_handle); - - smi_handle = Smi::New(strings_header_offset); - data.SetAt(kStringsHeaderOffset, smi_handle); - - smi_handle = Smi::New(strings_contents_offset); - data.SetAt(kStringsContentsOffset, smi_handle); - - smi_handle = Smi::New(object_offsets_offset); - data.SetAt(kObjectOffsetsOffset, smi_handle); - - smi_handle = Smi::New(num_objects); - data.SetAt(kNumObjects, smi_handle); - - smi_handle = Smi::New(objects_contents_offset); - data.SetAt(kObjectsContentsOffset, smi_handle); - - smi_handle = Smi::New(main_offset); - data.SetAt(kMainOffset, smi_handle); - - smi_handle = Smi::New(num_libraries); - data.SetAt(kNumLibraries, smi_handle); - - smi_handle = Smi::New(library_index_offset); - data.SetAt(kLibraryIndexOffset, smi_handle); - - smi_handle = Smi::New(libraries_offset); - data.SetAt(kLibrariesOffset, smi_handle); - - smi_handle = Smi::New(num_classes); - data.SetAt(kNumClasses, smi_handle); - - smi_handle = Smi::New(classes_offset); - data.SetAt(kClassesOffset, smi_handle); - - smi_handle = Smi::New(members_offset); - data.SetAt(kMembersOffset, smi_handle); - - smi_handle = Smi::New(num_codes); - data.SetAt(kNumCodes, smi_handle); - - smi_handle = Smi::New(codes_offset); - data.SetAt(kCodesOffset, smi_handle); - - smi_handle = Smi::New(source_positions_offset); - data.SetAt(kSourcePositionsOffset, smi_handle); - - smi_handle = Smi::New(source_files_offset); - data.SetAt(kSourceFilesOffset, smi_handle); - - smi_handle = Smi::New(line_starts_offset); - data.SetAt(kLineStartsOffset, smi_handle); - - smi_handle = Smi::New(local_variables_offset); - data.SetAt(kLocalVariablesOffset, smi_handle); - - smi_handle = Smi::New(annotations_offset); - data.SetAt(kAnnotationsOffset, smi_handle); - - return data.raw(); -} - -ErrorPtr BytecodeReader::ReadFunctionBytecode(Thread* thread, - const Function& function) { - ASSERT(!FLAG_precompiled_mode); - ASSERT(!function.HasBytecode()); - ASSERT(thread->sticky_error() == Error::null()); - ASSERT(Thread::Current()->IsMutatorThread()); - - VMTagScope tagScope(thread, VMTag::kLoadBytecodeTagId); - -#if defined(SUPPORT_TIMELINE) - TimelineBeginEndScope tbes(thread, Timeline::GetCompilerStream(), - "BytecodeReader::ReadFunctionBytecode"); - // This increases bytecode reading time by ~7%, so only keep it around for - // debugging. -#if defined(DEBUG) - tbes.SetNumArguments(1); - tbes.CopyArgument(0, "Function", function.ToQualifiedCString()); -#endif // defined(DEBUG) -#endif // !defined(SUPPORT_TIMELINE) - - LongJumpScope jump; - if (setjmp(*jump.Set()) == 0) { - StackZone stack_zone(thread); - Zone* const zone = stack_zone.GetZone(); - HANDLESCOPE(thread); - - auto& bytecode = Bytecode::Handle(zone); - - switch (function.kind()) { - case FunctionLayout::kImplicitGetter: - bytecode = Object::implicit_getter_bytecode().raw(); - break; - case FunctionLayout::kImplicitSetter: - bytecode = Object::implicit_setter_bytecode().raw(); - break; - case FunctionLayout::kImplicitStaticGetter: - if (!IsStaticFieldGetterGeneratedAsInitializer(function, zone)) { - bytecode = Object::implicit_static_getter_bytecode().raw(); - } - break; - case FunctionLayout::kMethodExtractor: - bytecode = Object::method_extractor_bytecode().raw(); - break; - case FunctionLayout::kInvokeFieldDispatcher: - if (Class::Handle(zone, function.Owner()).id() == kClosureCid) { - bytecode = Object::invoke_closure_bytecode().raw(); - } else { - bytecode = Object::invoke_field_bytecode().raw(); - } - break; - case FunctionLayout::kNoSuchMethodDispatcher: - bytecode = Object::nsm_dispatcher_bytecode().raw(); - break; - case FunctionLayout::kDynamicInvocationForwarder: { - const Function& target = - Function::Handle(zone, function.ForwardingTarget()); - if (!target.HasBytecode()) { - // The forwarder will use the target's bytecode to handle optional - // parameters. - const Error& error = - Error::Handle(zone, ReadFunctionBytecode(thread, target)); - if (!error.IsNull()) { - return error.raw(); - } - } - { - const Script& script = Script::Handle(zone, target.script()); - TranslationHelper translation_helper(thread); - translation_helper.InitFromScript(script); - - ActiveClass active_class; - BytecodeComponentData bytecode_component( - &Array::Handle(zone, translation_helper.GetBytecodeComponent())); - ASSERT(!bytecode_component.IsNull()); - BytecodeReaderHelper bytecode_reader( - &translation_helper, &active_class, &bytecode_component); - - const Array& checks = Array::Handle( - zone, bytecode_reader.CreateForwarderChecks(target)); - function.SetForwardingChecks(checks); - } - bytecode = Object::dynamic_invocation_forwarder_bytecode().raw(); - } break; - default: - break; - } - - if (!bytecode.IsNull()) { - function.AttachBytecode(bytecode); - } else if (function.is_declared_in_bytecode()) { - const intptr_t code_offset = function.bytecode_offset(); - if (code_offset != 0) { - CompilerState compiler_state(thread, FLAG_precompiled_mode); - - const Script& script = Script::Handle(zone, function.script()); - TranslationHelper translation_helper(thread); - translation_helper.InitFromScript(script); - - ActiveClass active_class; - - // Setup a [ActiveClassScope] and a [ActiveMemberScope] which will be - // used e.g. for type translation. - const Class& klass = Class::Handle(zone, function.Owner()); - Function& outermost_function = - Function::Handle(zone, function.GetOutermostFunction()); - - ActiveClassScope active_class_scope(&active_class, &klass); - ActiveMemberScope active_member(&active_class, &outermost_function); - - BytecodeComponentData bytecode_component( - &Array::Handle(zone, translation_helper.GetBytecodeComponent())); - ASSERT(!bytecode_component.IsNull()); - BytecodeReaderHelper bytecode_reader(&translation_helper, &active_class, - &bytecode_component); - - bytecode_reader.ReadCode(function, code_offset); - } - } - return Error::null(); - } else { - return thread->StealStickyError(); - } -} - -ObjectPtr BytecodeReader::ReadAnnotation(const Field& annotation_field) { - ASSERT(annotation_field.is_declared_in_bytecode()); - - Thread* thread = Thread::Current(); - Zone* zone = thread->zone(); - ASSERT(thread->IsMutatorThread()); - - const Script& script = Script::Handle(zone, annotation_field.Script()); - TranslationHelper translation_helper(thread); - translation_helper.InitFromScript(script); - - ActiveClass active_class; - - BytecodeComponentData bytecode_component( - &Array::Handle(zone, translation_helper.GetBytecodeComponent())); - ASSERT(!bytecode_component.IsNull()); - BytecodeReaderHelper bytecode_reader(&translation_helper, &active_class, - &bytecode_component); - - AlternativeReadingScope alt(&bytecode_reader.reader(), - annotation_field.bytecode_offset()); - - return bytecode_reader.ReadObject(); -} - -ArrayPtr BytecodeReader::ReadExtendedAnnotations(const Field& annotation_field, - intptr_t count) { - ASSERT(annotation_field.is_declared_in_bytecode()); - - Thread* thread = Thread::Current(); - Zone* zone = thread->zone(); - ASSERT(thread->IsMutatorThread()); - - const Script& script = Script::Handle(zone, annotation_field.Script()); - TranslationHelper translation_helper(thread); - translation_helper.InitFromScript(script); - - ActiveClass active_class; - - BytecodeComponentData bytecode_component( - &Array::Handle(zone, translation_helper.GetBytecodeComponent())); - ASSERT(!bytecode_component.IsNull()); - BytecodeReaderHelper bytecode_reader(&translation_helper, &active_class, - &bytecode_component); - - AlternativeReadingScope alt(&bytecode_reader.reader(), - annotation_field.bytecode_offset()); - - bytecode_reader.ReadObject(); // Discard main annotation. - - Array& result = Array::Handle(zone, Array::New(count)); - Object& element = Object::Handle(zone); - for (intptr_t i = 0; i < count; i++) { - element = bytecode_reader.ReadObject(); - result.SetAt(i, element); - } - return result.raw(); -} - -void BytecodeReader::ResetObjectTable(const KernelProgramInfo& info) { - Thread* thread = Thread::Current(); - TranslationHelper translation_helper(thread); - translation_helper.InitFromKernelProgramInfo(info); - ActiveClass active_class; - BytecodeComponentData bytecode_component(&Array::Handle( - thread->zone(), translation_helper.GetBytecodeComponent())); - ASSERT(!bytecode_component.IsNull()); - BytecodeReaderHelper bytecode_reader(&translation_helper, &active_class, - &bytecode_component); - bytecode_reader.ResetObjects(); -} - -void BytecodeReader::LoadClassDeclaration(const Class& cls) { - TIMELINE_DURATION(Thread::Current(), Compiler, - "BytecodeReader::LoadClassDeclaration"); - - ASSERT(cls.is_declared_in_bytecode()); - ASSERT(!cls.is_declaration_loaded()); - - Thread* thread = Thread::Current(); - Zone* zone = thread->zone(); - ASSERT(thread->IsMutatorThread()); - - const Script& script = Script::Handle(zone, cls.script()); - TranslationHelper translation_helper(thread); - translation_helper.InitFromScript(script); - - ActiveClass active_class; - ActiveClassScope active_class_scope(&active_class, &cls); - - BytecodeComponentData bytecode_component( - &Array::Handle(zone, translation_helper.GetBytecodeComponent())); - ASSERT(!bytecode_component.IsNull()); - BytecodeReaderHelper bytecode_reader(&translation_helper, &active_class, - &bytecode_component); - - AlternativeReadingScope alt(&bytecode_reader.reader(), cls.bytecode_offset()); - - bytecode_reader.ReadClassDeclaration(cls); -} - -void BytecodeReader::FinishClassLoading(const Class& cls) { - ASSERT(cls.is_declared_in_bytecode()); - - Thread* thread = Thread::Current(); - Zone* zone = thread->zone(); - ASSERT(thread->IsMutatorThread()); - - const Script& script = Script::Handle(zone, cls.script()); - TranslationHelper translation_helper(thread); - translation_helper.InitFromScript(script); - - ActiveClass active_class; - ActiveClassScope active_class_scope(&active_class, &cls); - - BytecodeComponentData bytecode_component( - &Array::Handle(zone, translation_helper.GetBytecodeComponent())); - ASSERT(!bytecode_component.IsNull()); - BytecodeReaderHelper bytecode_reader(&translation_helper, &active_class, - &bytecode_component); - - AlternativeReadingScope alt(&bytecode_reader.reader(), cls.bytecode_offset()); - - // If this is a dart:internal.ClassID class ignore field declarations - // contained in the Kernel file and instead inject our own const - // fields. - const bool discard_fields = cls.InjectCIDFields(); - - bytecode_reader.ReadMembers(cls, discard_fields); -} - -ObjectPtr BytecodeReader::GetBytecodeAttribute(const Object& key, - const String& name) { - Thread* thread = Thread::Current(); - Zone* zone = thread->zone(); - const auto* object_store = thread->isolate()->object_store(); - if (object_store->bytecode_attributes() == Object::null()) { - return Object::null(); - } - BytecodeAttributesMap map(object_store->bytecode_attributes()); - const auto& attrs = Array::CheckedHandle(zone, map.GetOrNull(key)); - ASSERT(map.Release().raw() == object_store->bytecode_attributes()); - if (attrs.IsNull()) { - return Object::null(); - } - auto& obj = Object::Handle(zone); - for (intptr_t i = 0, n = attrs.Length(); i + 1 < n; i += 2) { - obj = attrs.At(i); - if (obj.raw() == name.raw()) { - return attrs.At(i + 1); - } - } - return Object::null(); -} - -InferredTypeMetadata InferredTypeBytecodeAttribute::GetInferredTypeAt( - Zone* zone, - const Array& attr, - intptr_t index) { - ASSERT(index + kNumElements <= attr.Length()); - const auto& type = AbstractType::CheckedHandle(zone, attr.At(index + 1)); - const intptr_t flags = Smi::Value(Smi::RawCast(attr.At(index + 2))); - if (!type.IsNull()) { - intptr_t cid = Type::Cast(type).type_class_id(); - return InferredTypeMetadata(cid, flags); - } else { - return InferredTypeMetadata(kDynamicCid, flags); - } -} - -#if !defined(PRODUCT) -LocalVarDescriptorsPtr BytecodeReader::ComputeLocalVarDescriptors( - Zone* zone, - const Function& function, - const Bytecode& bytecode) { - ASSERT(function.is_declared_in_bytecode()); - ASSERT(function.HasBytecode()); - ASSERT(!bytecode.IsNull()); - ASSERT(function.bytecode() == bytecode.raw()); - - LocalVarDescriptorsBuilder vars; - - if (function.IsLocalFunction()) { - const auto& parent = Function::Handle(zone, function.parent_function()); - ASSERT(parent.is_declared_in_bytecode() && parent.HasBytecode()); - const auto& parent_bytecode = Bytecode::Handle(zone, parent.bytecode()); - const auto& parent_vars = LocalVarDescriptors::Handle( - zone, parent_bytecode.GetLocalVarDescriptors()); - for (intptr_t i = 0; i < parent_vars.Length(); ++i) { - LocalVarDescriptorsLayout::VarInfo var_info; - parent_vars.GetInfo(i, &var_info); - // Include parent's context variable if variable's scope - // intersects with the local function range. - // It is not enough to check if local function is declared within the - // scope of variable, because in case of async functions closure has - // the same range as original function. - if (var_info.kind() == LocalVarDescriptorsLayout::kContextVar && - ((var_info.begin_pos <= function.token_pos() && - function.token_pos() <= var_info.end_pos) || - (function.token_pos() <= var_info.begin_pos && - var_info.begin_pos <= function.end_token_pos()))) { - vars.Add(LocalVarDescriptorsBuilder::VarDesc{ - &String::Handle(zone, parent_vars.GetName(i)), var_info}); - } - } - } - - if (bytecode.HasLocalVariablesInfo()) { - intptr_t scope_id = 0; - intptr_t context_level = -1; - BytecodeLocalVariablesIterator local_vars(zone, bytecode); - while (local_vars.MoveNext()) { - switch (local_vars.Kind()) { - case BytecodeLocalVariablesIterator::kScope: { - ++scope_id; - context_level = local_vars.ContextLevel(); - } break; - case BytecodeLocalVariablesIterator::kVariableDeclaration: { - LocalVarDescriptorsBuilder::VarDesc desc; - desc.name = &String::Handle(zone, local_vars.Name()); - if (local_vars.IsCaptured()) { - desc.info.set_kind(LocalVarDescriptorsLayout::kContextVar); - desc.info.scope_id = context_level; - desc.info.set_index(local_vars.Index()); - } else { - desc.info.set_kind(LocalVarDescriptorsLayout::kStackVar); - desc.info.scope_id = scope_id; - if (local_vars.Index() < 0) { - // Parameter - ASSERT(local_vars.Index() < -kKBCParamEndSlotFromFp); - desc.info.set_index(-local_vars.Index() - kKBCParamEndSlotFromFp); - } else { - desc.info.set_index(-local_vars.Index()); - } - } - desc.info.declaration_pos = local_vars.DeclarationTokenPos(); - desc.info.begin_pos = local_vars.StartTokenPos(); - desc.info.end_pos = local_vars.EndTokenPos(); - vars.Add(desc); - } break; - case BytecodeLocalVariablesIterator::kContextVariable: { - ASSERT(local_vars.Index() >= 0); - const intptr_t context_variable_index = -local_vars.Index(); - LocalVarDescriptorsBuilder::VarDesc desc; - desc.name = &Symbols::CurrentContextVar(); - desc.info.set_kind(LocalVarDescriptorsLayout::kSavedCurrentContext); - desc.info.scope_id = 0; - desc.info.declaration_pos = TokenPosition::kMinSource; - desc.info.begin_pos = TokenPosition::kMinSource; - desc.info.end_pos = TokenPosition::kMinSource; - desc.info.set_index(context_variable_index); - vars.Add(desc); - } break; - } - } - } - - return vars.Done(); -} -#endif // !defined(PRODUCT) - -bool IsStaticFieldGetterGeneratedAsInitializer(const Function& function, - Zone* zone) { - ASSERT(function.kind() == FunctionLayout::kImplicitStaticGetter); - - const auto& field = Field::Handle(zone, function.accessor_field()); - return field.is_declared_in_bytecode() && field.is_const() && - field.has_nontrivial_initializer(); -} - -} // namespace kernel -} // namespace dart diff --git a/runtime/vm/compiler/frontend/bytecode_reader.h b/runtime/vm/compiler/frontend/bytecode_reader.h deleted file mode 100644 index ee8444fcb26..00000000000 --- a/runtime/vm/compiler/frontend/bytecode_reader.h +++ /dev/null @@ -1,589 +0,0 @@ -// Copyright (c) 2018, the Dart project authors. Please see the AUTHORS file -// for details. All rights reserved. Use of this source code is governed by a -// BSD-style license that can be found in the LICENSE file. - -#ifndef RUNTIME_VM_COMPILER_FRONTEND_BYTECODE_READER_H_ -#define RUNTIME_VM_COMPILER_FRONTEND_BYTECODE_READER_H_ - -#if defined(DART_PRECOMPILED_RUNTIME) -#error "AOT runtime should not use compiler sources (including header files)" -#endif // defined(DART_PRECOMPILED_RUNTIME) - -#include "vm/compiler/frontend/kernel_translation_helper.h" -#include "vm/constants_kbc.h" -#include "vm/object.h" - -namespace dart { -namespace kernel { - -class BytecodeComponentData; - -// Helper class which provides access to bytecode metadata. -class BytecodeMetadataHelper : public MetadataHelper { - public: - static const char* tag() { return "vm.bytecode"; } - - explicit BytecodeMetadataHelper(KernelReaderHelper* helper, - ActiveClass* active_class); - - void ParseBytecodeFunction(ParsedFunction* parsed_function); - - // Read all library declarations. - bool ReadLibraries(); - - // Read specific library declaration. - void ReadLibrary(const Library& library); - - // Scan through libraries in the bytecode component and figure out if any of - // them will replace libraries which are already loaded. - // Return true if bytecode component is found. - bool FindModifiedLibrariesForHotReload(BitVector* modified_libs, - bool* is_empty_program, - intptr_t* p_num_classes, - intptr_t* p_num_procedures); - - LibraryPtr GetMainLibrary(); - - ArrayPtr GetBytecodeComponent(); - ArrayPtr ReadBytecodeComponent(); - - private: - ActiveClass* const active_class_; - - DISALLOW_COPY_AND_ASSIGN(BytecodeMetadataHelper); -}; - -// Helper class for reading bytecode. -class BytecodeReaderHelper : public ValueObject { - public: - explicit BytecodeReaderHelper(TranslationHelper* translation_helper, - ActiveClass* active_class, - BytecodeComponentData* bytecode_component); - - Reader& reader() { return reader_; } - - void ReadCode(const Function& function, intptr_t code_offset); - - ArrayPtr CreateForwarderChecks(const Function& function); - - void ReadMembers(const Class& cls, bool discard_fields); - - void ReadFieldDeclarations(const Class& cls, bool discard_fields); - void ReadFunctionDeclarations(const Class& cls); - void ReadClassDeclaration(const Class& cls); - void ReadLibraryDeclaration(const Library& library, bool lookup_classes); - void ReadLibraryDeclarations(intptr_t num_libraries); - void FindAndReadSpecificLibrary(const Library& library, - intptr_t num_libraries); - void FindModifiedLibrariesForHotReload(BitVector* modified_libs, - intptr_t num_libraries); - - void ParseBytecodeFunction(ParsedFunction* parsed_function, - const Function& function); - - LibraryPtr ReadMain(); - - ArrayPtr ReadBytecodeComponent(intptr_t md_offset); - void ResetObjects(); - - // Fills in [is_covariant] and [is_generic_covariant_impl] vectors - // according to covariance attributes of [function] parameters. - // - // [function] should be declared in bytecode. - // [is_covariant] and [is_generic_covariant_impl] should contain bitvectors - // of function.NumParameters() length. - void ReadParameterCovariance(const Function& function, - BitVector* is_covariant, - BitVector* is_generic_covariant_impl); - - // Returns an flattened array of tuples {isFinal, defaultValue, metadata}, - // or an Error. - ObjectPtr BuildParameterDescriptor(const Function& function); - - // Read bytecode PackedObject. - ObjectPtr ReadObject(); - - private: - // These constants should match corresponding constants in class ObjectHandle - // (pkg/vm/lib/bytecode/object_table.dart). - static const int kReferenceBit = 1 << 0; - static const int kIndexShift = 1; - static const int kKindShift = 1; - static const int kKindMask = 0x0f; - static const int kFlagBit0 = 1 << 5; - static const int kFlagBit1 = 1 << 6; - static const int kFlagBit2 = 1 << 7; - static const int kFlagBit3 = 1 << 8; - static const int kFlagBit4 = 1 << 9; - static const int kFlagBit5 = 1 << 10; - static const int kTagMask = (kFlagBit0 | kFlagBit1 | kFlagBit2 | kFlagBit3); - static const int kNullabilityMask = (kFlagBit4 | kFlagBit5); - static const int kFlagsMask = (kTagMask | kNullabilityMask); - - // Code flags, must be in sync with Code constants in - // pkg/vm/lib/bytecode/declarations.dart. - struct Code { - static const int kHasExceptionsTableFlag = 1 << 0; - static const int kHasSourcePositionsFlag = 1 << 1; - static const int kHasNullableFieldsFlag = 1 << 2; - static const int kHasClosuresFlag = 1 << 3; - static const int kHasParameterFlagsFlag = 1 << 4; - static const int kHasForwardingStubTargetFlag = 1 << 5; - static const int kHasDefaultFunctionTypeArgsFlag = 1 << 6; - static const int kHasLocalVariablesFlag = 1 << 7; - }; - - // Closure code flags, must be in sync with ClosureCode constants in - // pkg/vm/lib/bytecode/declarations.dart. - struct ClosureCode { - static const int kHasExceptionsTableFlag = 1 << 0; - static const int kHasSourcePositionsFlag = 1 << 1; - static const int kHasLocalVariablesFlag = 1 << 2; - }; - - // Parameter flags, must be in sync with ParameterDeclaration constants in - // pkg/vm/lib/bytecode/declarations.dart. - struct Parameter { - static const int kIsCovariantFlag = 1 << 0; - static const int kIsGenericCovariantImplFlag = 1 << 1; - static const int kIsFinalFlag = 1 << 2; - static const int kIsRequiredFlag = 1 << 3; - }; - - class FunctionTypeScope : public ValueObject { - public: - explicit FunctionTypeScope(BytecodeReaderHelper* bytecode_reader) - : bytecode_reader_(bytecode_reader), - saved_type_parameters_( - bytecode_reader->function_type_type_parameters_) {} - - ~FunctionTypeScope() { - bytecode_reader_->function_type_type_parameters_ = saved_type_parameters_; - } - - private: - BytecodeReaderHelper* bytecode_reader_; - const TypeArguments* const saved_type_parameters_; - }; - - class FunctionScope : public ValueObject { - public: - FunctionScope(BytecodeReaderHelper* bytecode_reader, - const Function& function, - const String& name, - const Class& cls) - : bytecode_reader_(bytecode_reader) { - ASSERT(bytecode_reader_->scoped_function_.IsNull()); - ASSERT(bytecode_reader_->scoped_function_name_.IsNull()); - ASSERT(bytecode_reader_->scoped_function_class_.IsNull()); - ASSERT(name.IsSymbol()); - bytecode_reader_->scoped_function_ = function.raw(); - bytecode_reader_->scoped_function_name_ = name.raw(); - bytecode_reader_->scoped_function_class_ = cls.raw(); - } - - ~FunctionScope() { - bytecode_reader_->scoped_function_ = Function::null(); - bytecode_reader_->scoped_function_name_ = String::null(); - bytecode_reader_->scoped_function_class_ = Class::null(); - } - - private: - BytecodeReaderHelper* bytecode_reader_; - }; - - void ReadClosureDeclaration(const Function& function, intptr_t closureIndex); - TypePtr ReadFunctionSignature(const Function& func, - bool has_optional_positional_params, - bool has_optional_named_params, - bool has_type_params, - bool has_positional_param_names, - bool has_parameter_flags, - Nullability nullability); - void ReadTypeParametersDeclaration(const Class& parameterized_class, - const Function& parameterized_function); - - // Read portion of constant pool corresponding to one function/closure. - // Start with [start_index], and stop when reaching EndClosureFunctionScope. - // Return index of the last read constant pool entry. - intptr_t ReadConstantPool(const Function& function, - const ObjectPool& pool, - intptr_t start_index); - - BytecodePtr ReadBytecode(const ObjectPool& pool); - void ReadExceptionsTable(const Bytecode& bytecode, bool has_exceptions_table); - void ReadSourcePositions(const Bytecode& bytecode, bool has_source_positions); - void ReadLocalVariables(const Bytecode& bytecode, bool has_local_variables); - TypedDataPtr NativeEntry(const Function& function, - const String& external_name); - StringPtr ConstructorName(const Class& cls, const String& name); - - ObjectPtr ReadObjectContents(uint32_t header); - ObjectPtr ReadConstObject(intptr_t tag); - ObjectPtr ReadType(intptr_t tag, Nullability nullability); - StringPtr ReadString(bool is_canonical = true); - ScriptPtr ReadSourceFile(const String& uri, intptr_t offset); - TypeArgumentsPtr ReadTypeArguments(); - void ReadAttributes(const Object& key); - PatchClassPtr GetPatchClass(const Class& cls, const Script& script); - void ParseForwarderFunction(ParsedFunction* parsed_function, - const Function& function, - const Function& target); - - bool IsExpressionEvaluationLibrary(const Library& library) const { - return expression_evaluation_library_ != nullptr && - expression_evaluation_library_->raw() == library.raw(); - } - - // Similar to cls.EnsureClassDeclaration, but may be more efficient if - // class is from the current kernel binary. - void LoadReferencedClass(const Class& cls); - - Reader reader_; - TranslationHelper& translation_helper_; - ActiveClass* const active_class_; - Thread* const thread_; - Zone* const zone_; - BytecodeComponentData* bytecode_component_; - Array* closures_ = nullptr; - const TypeArguments* function_type_type_parameters_ = nullptr; - GrowableObjectArray* pending_recursive_types_ = nullptr; - PatchClass* patch_class_ = nullptr; - Array* functions_ = nullptr; - intptr_t function_index_ = 0; - Function& scoped_function_; - String& scoped_function_name_; - Class& scoped_function_class_; - Library* expression_evaluation_library_ = nullptr; - bool loading_native_wrappers_library_ = false; - bool reading_type_arguments_of_recursive_type_ = false; - - DISALLOW_COPY_AND_ASSIGN(BytecodeReaderHelper); -}; - -class BytecodeComponentData : ValueObject { - public: - enum { - kVersion, - kStringsHeaderOffset, - kStringsContentsOffset, - kObjectOffsetsOffset, - kNumObjects, - kObjectsContentsOffset, - kMainOffset, - kNumLibraries, - kLibraryIndexOffset, - kLibrariesOffset, - kNumClasses, - kClassesOffset, - kMembersOffset, - kNumCodes, - kCodesOffset, - kSourcePositionsOffset, - kSourceFilesOffset, - kLineStartsOffset, - kLocalVariablesOffset, - kAnnotationsOffset, - kNumFields - }; - - explicit BytecodeComponentData(Array* data) : data_(*data) {} - - void Init(const Array& data) { data_ = data.raw(); } - - intptr_t GetVersion() const; - intptr_t GetStringsHeaderOffset() const; - intptr_t GetStringsContentsOffset() const; - intptr_t GetObjectOffsetsOffset() const; - intptr_t GetNumObjects() const; - intptr_t GetObjectsContentsOffset() const; - intptr_t GetMainOffset() const; - intptr_t GetNumLibraries() const; - intptr_t GetLibraryIndexOffset() const; - intptr_t GetLibrariesOffset() const; - intptr_t GetNumClasses() const; - intptr_t GetClassesOffset() const; - intptr_t GetMembersOffset() const; - intptr_t GetNumCodes() const; - intptr_t GetCodesOffset() const; - intptr_t GetSourcePositionsOffset() const; - intptr_t GetSourceFilesOffset() const; - intptr_t GetLineStartsOffset() const; - intptr_t GetLocalVariablesOffset() const; - intptr_t GetAnnotationsOffset() const; - void SetObject(intptr_t index, const Object& obj) const; - ObjectPtr GetObject(intptr_t index) const; - - bool IsNull() const { return data_.IsNull(); } - - static ArrayPtr New(Zone* zone, - intptr_t version, - intptr_t num_objects, - intptr_t strings_header_offset, - intptr_t strings_contents_offset, - intptr_t object_offsets_offset, - intptr_t objects_contents_offset, - intptr_t main_offset, - intptr_t num_libraries, - intptr_t library_index_offset, - intptr_t libraries_offset, - intptr_t num_classes, - intptr_t classes_offset, - intptr_t members_offset, - intptr_t num_codes, - intptr_t codes_offset, - intptr_t source_positions_offset, - intptr_t source_files_offset, - intptr_t line_starts_offset, - intptr_t local_variables_offset, - intptr_t annotations_offset, - Heap::Space space); - - private: - Array& data_; -}; - -class BytecodeReader : public AllStatic { - public: - // Reads bytecode for the given function and sets its bytecode field. - // Returns error (if any), or null. - static ErrorPtr ReadFunctionBytecode(Thread* thread, - const Function& function); - - // Read annotations for the given annotation field. - static ObjectPtr ReadAnnotation(const Field& annotation_field); - // Read the |count| annotations following given annotation field. - static ArrayPtr ReadExtendedAnnotations(const Field& annotation_field, - intptr_t count); - - static void ResetObjectTable(const KernelProgramInfo& info); - - // Read declaration of the given library. - static void LoadLibraryDeclaration(const Library& library); - - // Read declaration of the given class. - static void LoadClassDeclaration(const Class& cls); - - // Read members of the given class. - static void FinishClassLoading(const Class& cls); - - // Value of attribute [name] of Function/Field [key]. - static ObjectPtr GetBytecodeAttribute(const Object& key, const String& name); - -#if !defined(PRODUCT) - // Compute local variable descriptors for [function] with [bytecode]. - static LocalVarDescriptorsPtr ComputeLocalVarDescriptors( - Zone* zone, - const Function& function, - const Bytecode& bytecode); -#endif -}; - -class InferredTypeBytecodeAttribute : public AllStatic { - public: - // Number of array elements per entry in InferredType bytecode - // attribute (PC, type, flags). - static constexpr intptr_t kNumElements = 3; - - // Field type is the first entry with PC = -1. - static constexpr intptr_t kFieldTypePC = -1; - - // Returns PC at given index. - static intptr_t GetPCAt(const Array& attr, intptr_t index) { - return Smi::Value(Smi::RawCast(attr.At(index))); - } - - // Returns InferredType metadata at given index. - static InferredTypeMetadata GetInferredTypeAt(Zone* zone, - const Array& attr, - intptr_t index); -}; - -class BytecodeSourcePositionsIterator : ValueObject { - public: - // These constants should match corresponding constants in class - // SourcePositions (pkg/vm/lib/bytecode/source_positions.dart). - static const intptr_t kSyntheticCodeMarker = -1; - static const intptr_t kYieldPointMarker = -2; - - BytecodeSourcePositionsIterator(Zone* zone, const Bytecode& bytecode) - : reader_(ExternalTypedData::Handle(zone, bytecode.GetBinary(zone))) { - if (bytecode.HasSourcePositions()) { - reader_.set_offset(bytecode.source_positions_binary_offset()); - pairs_remaining_ = reader_.ReadUInt(); - } - } - - bool MoveNext() { - if (pairs_remaining_ == 0) { - return false; - } - ASSERT(pairs_remaining_ > 0); - --pairs_remaining_; - cur_bci_ += reader_.ReadUInt(); - cur_token_pos_ += reader_.ReadSLEB128(); - is_yield_point_ = false; - if (cur_token_pos_ == kYieldPointMarker) { - const bool result = MoveNext(); - is_yield_point_ = true; - return result; - } - return true; - } - - uword PcOffset() const { return cur_bci_; } - - TokenPosition TokenPos() const { - return (cur_token_pos_ == kSyntheticCodeMarker) - ? TokenPosition::kNoSource - : TokenPosition(cur_token_pos_); - } - - bool IsYieldPoint() const { return is_yield_point_; } - - private: - Reader reader_; - intptr_t pairs_remaining_ = 0; - intptr_t cur_bci_ = 0; - intptr_t cur_token_pos_ = 0; - bool is_yield_point_ = false; -}; - -class BytecodeLocalVariablesIterator : ValueObject { - public: - // These constants should match corresponding constants in - // pkg/vm/lib/bytecode/local_variable_table.dart. - enum { - kInvalid, - kScope, - kVariableDeclaration, - kContextVariable, - }; - - static const intptr_t kKindMask = 0xF; - static const intptr_t kIsCapturedFlag = 1 << 4; - - BytecodeLocalVariablesIterator(Zone* zone, const Bytecode& bytecode) - : reader_(ExternalTypedData::Handle(zone, bytecode.GetBinary(zone))), - object_pool_(ObjectPool::Handle(zone, bytecode.object_pool())) { - if (bytecode.HasLocalVariablesInfo()) { - reader_.set_offset(bytecode.local_variables_binary_offset()); - entries_remaining_ = reader_.ReadUInt(); - } - } - - bool MoveNext() { - if (entries_remaining_ <= 0) { - // Finished looking at the last entry, now we're done. - entries_remaining_ = -1; - return false; - } - --entries_remaining_; - cur_kind_and_flags_ = reader_.ReadByte(); - cur_start_pc_ += reader_.ReadSLEB128(); - switch (Kind()) { - case kScope: - cur_end_pc_ = cur_start_pc_ + reader_.ReadUInt(); - cur_index_ = reader_.ReadSLEB128(); - cur_token_pos_ = reader_.ReadPosition(); - cur_end_token_pos_ = reader_.ReadPosition(); - break; - case kVariableDeclaration: - cur_index_ = reader_.ReadSLEB128(); - cur_name_ = reader_.ReadUInt(); - cur_type_ = reader_.ReadUInt(); - cur_declaration_token_pos_ = reader_.ReadPosition(); - cur_token_pos_ = reader_.ReadPosition(); - break; - case kContextVariable: - cur_index_ = reader_.ReadSLEB128(); - break; - } - return true; - } - - // Returns true after iterator moved past the last entry and - // MoveNext() returned false. - bool IsDone() const { return entries_remaining_ < 0; } - - intptr_t Kind() const { return cur_kind_and_flags_ & kKindMask; } - bool IsScope() const { return Kind() == kScope; } - bool IsVariableDeclaration() const { return Kind() == kVariableDeclaration; } - bool IsContextVariable() const { return Kind() == kContextVariable; } - - intptr_t StartPC() const { return cur_start_pc_; } - intptr_t EndPC() const { - ASSERT(IsScope() || IsVariableDeclaration()); - return cur_end_pc_; - } - intptr_t ContextLevel() const { - ASSERT(IsScope()); - return cur_index_; - } - TokenPosition StartTokenPos() const { - ASSERT(IsScope() || IsVariableDeclaration()); - return cur_token_pos_; - } - TokenPosition EndTokenPos() const { - ASSERT(IsScope() || IsVariableDeclaration()); - return cur_end_token_pos_; - } - intptr_t Index() const { - ASSERT(IsVariableDeclaration() || IsContextVariable()); - return cur_index_; - } - StringPtr Name() const { - ASSERT(IsVariableDeclaration()); - return String::RawCast(object_pool_.ObjectAt(cur_name_)); - } - AbstractTypePtr Type() const { - ASSERT(IsVariableDeclaration()); - return AbstractType::RawCast(object_pool_.ObjectAt(cur_type_)); - } - TokenPosition DeclarationTokenPos() const { - ASSERT(IsVariableDeclaration()); - return cur_declaration_token_pos_; - } - bool IsCaptured() const { - ASSERT(IsVariableDeclaration()); - return (cur_kind_and_flags_ & kIsCapturedFlag) != 0; - } - - private: - Reader reader_; - const ObjectPool& object_pool_; - intptr_t entries_remaining_ = 0; - intptr_t cur_kind_and_flags_ = 0; - intptr_t cur_start_pc_ = 0; - intptr_t cur_end_pc_ = 0; - intptr_t cur_index_ = -1; - intptr_t cur_name_ = -1; - intptr_t cur_type_ = -1; - TokenPosition cur_token_pos_ = TokenPosition::kNoSource; - TokenPosition cur_declaration_token_pos_ = TokenPosition::kNoSource; - TokenPosition cur_end_token_pos_ = TokenPosition::kNoSource; -}; - -class BytecodeAttributesMapTraits { - public: - static const char* Name() { return "BytecodeAttributesMapTraits"; } - static bool ReportStats() { return false; } - - static bool IsMatch(const Object& a, const Object& b) { - return a.raw() == b.raw(); - } - - static uword Hash(const Object& key) { - return String::HashRawSymbol(key.IsFunction() ? Function::Cast(key).name() - : Field::Cast(key).name()); - } -}; -typedef UnorderedHashMap BytecodeAttributesMap; - -bool IsStaticFieldGetterGeneratedAsInitializer(const Function& function, - Zone* zone); - -} // namespace kernel -} // namespace dart - -#endif // RUNTIME_VM_COMPILER_FRONTEND_BYTECODE_READER_H_ diff --git a/runtime/vm/compiler/frontend/bytecode_scope_builder.cc b/runtime/vm/compiler/frontend/bytecode_scope_builder.cc deleted file mode 100644 index c88a2279e64..00000000000 --- a/runtime/vm/compiler/frontend/bytecode_scope_builder.cc +++ /dev/null @@ -1,194 +0,0 @@ -// Copyright (c) 2018, the Dart project authors. Please see the AUTHORS file -// for details. All rights reserved. Use of this source code is governed by a -// BSD-style license that can be found in the LICENSE file. - -#include "vm/compiler/frontend/bytecode_scope_builder.h" - -#include "vm/compiler/frontend/bytecode_reader.h" - -namespace dart { -namespace kernel { - -#define Z (zone_) - -BytecodeScopeBuilder::BytecodeScopeBuilder(ParsedFunction* parsed_function) - : parsed_function_(parsed_function), - zone_(parsed_function->zone()), - scope_(nullptr) {} - -void BytecodeScopeBuilder::BuildScopes() { - if (parsed_function_->scope() != nullptr) { - return; // Scopes are already built. - } - - const Function& function = parsed_function_->function(); - - LocalScope* enclosing_scope = nullptr; - if (function.IsImplicitClosureFunction() && !function.is_static()) { - // Create artificial enclosing scope for the tear-off that contains - // captured receiver value. This ensure that AssertAssignable will correctly - // load instantiator type arguments if they are needed. - LocalVariable* receiver_variable = - MakeReceiverVariable(/* is_parameter = */ false); - receiver_variable->set_is_captured(); - enclosing_scope = new (Z) LocalScope(NULL, 0, 0); - enclosing_scope->set_context_level(0); - enclosing_scope->AddVariable(receiver_variable); - enclosing_scope->AddContextVariable(receiver_variable); - } - scope_ = new (Z) LocalScope(enclosing_scope, 0, 0); - scope_->set_begin_token_pos(function.token_pos()); - scope_->set_end_token_pos(function.end_token_pos()); - - // Add function type arguments variable before current context variable. - if ((function.IsGeneric() || function.HasGenericParent())) { - LocalVariable* type_args_var = MakeVariable( - Symbols::FunctionTypeArgumentsVar(), AbstractType::dynamic_type()); - scope_->AddVariable(type_args_var); - parsed_function_->set_function_type_arguments(type_args_var); - } - - bool needs_expr_temp = false; - if (parsed_function_->has_arg_desc_var()) { - needs_expr_temp = true; - scope_->AddVariable(parsed_function_->arg_desc_var()); - } - - LocalVariable* context_var = parsed_function_->current_context_var(); - context_var->set_is_forced_stack(); - scope_->AddVariable(context_var); - - parsed_function_->set_scope(scope_); - - switch (function.kind()) { - case FunctionLayout::kImplicitClosureFunction: { - ASSERT(function.NumImplicitParameters() == 1); - - const auto& parent = Function::Handle(Z, function.parent_function()); - const auto& target = - Function::Handle(Z, function.ImplicitClosureTarget(Z)); - - // For BuildGraphOfNoSuchMethodForwarder, since closures no longer - // require arg_desc_var in all cases. - if (target.IsNull() || - (parent.num_fixed_parameters() != target.num_fixed_parameters())) { - needs_expr_temp = true; - } - - LocalVariable* closure_parameter = MakeVariable( - Symbols::ClosureParameter(), AbstractType::dynamic_type()); - closure_parameter->set_is_forced_stack(); - scope_->InsertParameterAt(0, closure_parameter); - - // Type check all parameters by default. - // This may be overridden with parameter flags in - // BytecodeReaderHelper::ParseForwarderFunction. - AddParameters(function, LocalVariable::kDoTypeCheck); - break; - } - - case FunctionLayout::kImplicitGetter: - case FunctionLayout::kImplicitSetter: { - const bool is_setter = function.IsImplicitSetterFunction(); - const bool is_method = !function.IsStaticFunction(); - const Field& field = Field::Handle(Z, function.accessor_field()); - intptr_t pos = 0; - if (is_method) { - MakeReceiverVariable(/* is_parameter = */ true); - ++pos; - } - if (is_setter) { - LocalVariable* setter_value = MakeVariable( - Symbols::Value(), - AbstractType::ZoneHandle(Z, function.ParameterTypeAt(pos))); - scope_->InsertParameterAt(pos++, setter_value); - - if (is_method) { - if (field.is_covariant()) { - setter_value->set_is_explicit_covariant_parameter(); - } else { - const bool needs_type_check = - field.is_generic_covariant_impl() && - kernel::ProcedureAttributesOf(field, Z).has_non_this_uses; - if (!needs_type_check) { - setter_value->set_type_check_mode( - LocalVariable::kTypeCheckedByCaller); - } - } - } - } - break; - } - case FunctionLayout::kImplicitStaticGetter: { - ASSERT(!IsStaticFieldGetterGeneratedAsInitializer(function, Z)); - break; - } - case FunctionLayout::kDynamicInvocationForwarder: { - // Create [this] variable. - MakeReceiverVariable(/* is_parameter = */ true); - - // Type check all parameters by default. - // This may be overridden with parameter flags in - // BytecodeReaderHelper::ParseForwarderFunction. - AddParameters(function, LocalVariable::kDoTypeCheck); - break; - } - case FunctionLayout::kMethodExtractor: { - // Add a receiver parameter. Though it is captured, we emit code to - // explicitly copy it to a fixed offset in a freshly-allocated context - // instead of using the generic code for regular functions. - // Therefore, it isn't necessary to mark it as captured here. - MakeReceiverVariable(/* is_parameter = */ true); - break; - } - default: - UNREACHABLE(); - } - - if (needs_expr_temp) { - scope_->AddVariable(parsed_function_->EnsureExpressionTemp()); - } - if (parsed_function_->function().MayHaveUncheckedEntryPoint()) { - scope_->AddVariable(parsed_function_->EnsureEntryPointsTemp()); - } - parsed_function_->AllocateVariables(); -} - -// TODO(alexmarkov): pass bitvectors of parameter covariance to set type -// check mode before AllocateVariables. -void BytecodeScopeBuilder::AddParameters(const Function& function, - LocalVariable::TypeCheckMode mode) { - for (intptr_t i = function.NumImplicitParameters(), - n = function.NumParameters(); - i < n; ++i) { - // LocalVariable caches handles, so new handles are created for each - // parameter. - String& name = String::ZoneHandle(Z, function.ParameterNameAt(i)); - AbstractType& type = - AbstractType::ZoneHandle(Z, function.ParameterTypeAt(i)); - - LocalVariable* variable = MakeVariable(name, type); - variable->set_type_check_mode(mode); - scope_->InsertParameterAt(i, variable); - } -} - -LocalVariable* BytecodeScopeBuilder::MakeVariable(const String& name, - const AbstractType& type) { - return new (Z) LocalVariable(TokenPosition::kNoSource, - TokenPosition::kNoSource, name, type, nullptr); -} - -LocalVariable* BytecodeScopeBuilder::MakeReceiverVariable(bool is_parameter) { - const auto& cls = Class::Handle(Z, parsed_function_->function().Owner()); - const auto& type = Type::ZoneHandle(Z, cls.DeclarationType()); - LocalVariable* receiver_variable = MakeVariable(Symbols::This(), type); - parsed_function_->set_receiver_var(receiver_variable); - if (is_parameter) { - scope_->InsertParameterAt(0, receiver_variable); - } - return receiver_variable; -} - -} // namespace kernel -} // namespace dart diff --git a/runtime/vm/compiler/frontend/bytecode_scope_builder.h b/runtime/vm/compiler/frontend/bytecode_scope_builder.h deleted file mode 100644 index 8f96b87f92a..00000000000 --- a/runtime/vm/compiler/frontend/bytecode_scope_builder.h +++ /dev/null @@ -1,41 +0,0 @@ -// Copyright (c) 2019, the Dart project authors. Please see the AUTHORS file -// for details. All rights reserved. Use of this source code is governed by a -// BSD-style license that can be found in the LICENSE file. - -#ifndef RUNTIME_VM_COMPILER_FRONTEND_BYTECODE_SCOPE_BUILDER_H_ -#define RUNTIME_VM_COMPILER_FRONTEND_BYTECODE_SCOPE_BUILDER_H_ - -#if defined(DART_PRECOMPILED_RUNTIME) -#error "AOT runtime should not use compiler sources (including header files)" -#endif // defined(DART_PRECOMPILED_RUNTIME) - -#include "vm/object.h" -#include "vm/parser.h" // For ParsedFunction. -#include "vm/scopes.h" - -namespace dart { -namespace kernel { - -// Builds scopes, populates parameters and local variables for -// certain functions declared in bytecode. -class BytecodeScopeBuilder : public ValueObject { - public: - explicit BytecodeScopeBuilder(ParsedFunction* parsed_function); - - void BuildScopes(); - - private: - void AddParameters(const Function& function, - LocalVariable::TypeCheckMode mode); - LocalVariable* MakeVariable(const String& name, const AbstractType& type); - LocalVariable* MakeReceiverVariable(bool is_parameter); - - ParsedFunction* parsed_function_; - Zone* zone_; - LocalScope* scope_; -}; - -} // namespace kernel -} // namespace dart - -#endif // RUNTIME_VM_COMPILER_FRONTEND_BYTECODE_SCOPE_BUILDER_H_ diff --git a/runtime/vm/compiler/frontend/constant_reader.cc b/runtime/vm/compiler/frontend/constant_reader.cc index 2aa6ed56be2..2bb6f2b6df1 100644 --- a/runtime/vm/compiler/frontend/constant_reader.cc +++ b/runtime/vm/compiler/frontend/constant_reader.cc @@ -212,7 +212,7 @@ InstancePtr ConstantReader::ReadConstantInternal(intptr_t constant_offset) { case kInstanceConstant: { const NameIndex index = reader.ReadCanonicalNameReference(); const auto& klass = Class::Handle(Z, H.LookupClassByKernelClass(index)); - if (!klass.is_declaration_loaded() && !klass.is_declared_in_bytecode()) { + if (!klass.is_declaration_loaded()) { FATAL1( "Trying to evaluate an instance constant whose references class " "%s is not loaded yet.", diff --git a/runtime/vm/compiler/frontend/kernel_binary_flowgraph.cc b/runtime/vm/compiler/frontend/kernel_binary_flowgraph.cc index b118c2bfc8b..bcb3306d94e 100644 --- a/runtime/vm/compiler/frontend/kernel_binary_flowgraph.cc +++ b/runtime/vm/compiler/frontend/kernel_binary_flowgraph.cc @@ -5,8 +5,6 @@ #include "vm/compiler/frontend/kernel_binary_flowgraph.h" #include "vm/compiler/ffi/callback.h" -#include "vm/compiler/frontend/bytecode_flow_graph_builder.h" -#include "vm/compiler/frontend/bytecode_reader.h" #include "vm/compiler/frontend/flow_graph_builder.h" // For dart::FlowGraphBuilder::SimpleInstanceOfType. #include "vm/compiler/frontend/prologue_builder.h" #include "vm/compiler/jit/compiler.h" @@ -15,9 +13,6 @@ #include "vm/stack_frame.h" namespace dart { - -DECLARE_FLAG(bool, enable_interpreter); - namespace kernel { #define Z (zone_) @@ -1055,55 +1050,6 @@ FlowGraph* StreamingFlowGraphBuilder::BuildGraph() { ActiveMemberScope active_member(active_class(), &outermost_function); ActiveTypeParametersScope active_type_params(active_class(), function, Z); - if (function.is_declared_in_bytecode()) { - bytecode_metadata_helper_.ParseBytecodeFunction(parsed_function()); - - switch (function.kind()) { - case FunctionLayout::kImplicitClosureFunction: - return B->BuildGraphOfImplicitClosureFunction(function); - case FunctionLayout::kImplicitGetter: - case FunctionLayout::kImplicitSetter: - return B->BuildGraphOfFieldAccessor(function); - case FunctionLayout::kImplicitStaticGetter: { - if (IsStaticFieldGetterGeneratedAsInitializer(function, Z)) { - break; - } - return B->BuildGraphOfFieldAccessor(function); - } - case FunctionLayout::kDynamicInvocationForwarder: - return B->BuildGraphOfDynamicInvocationForwarder(function); - case FunctionLayout::kMethodExtractor: - return B->BuildGraphOfMethodExtractor(function); - case FunctionLayout::kNoSuchMethodDispatcher: - return B->BuildGraphOfNoSuchMethodDispatcher(function); - default: - break; - } - - ASSERT(function.HasBytecode()); - - BytecodeFlowGraphBuilder bytecode_compiler( - flow_graph_builder_, parsed_function(), - &(flow_graph_builder_->ic_data_array_)); - - if (B->IsRecognizedMethodForFlowGraph(function)) { - bytecode_compiler.CreateParameterVariables(); - return B->BuildGraphOfRecognizedMethod(function); - } - - return bytecode_compiler.BuildGraph(); - } - - // Certain special functions could have a VM-internal bytecode - // attached to them. - ASSERT((!function.HasBytecode()) || - (function.kind() == FunctionLayout::kImplicitGetter) || - (function.kind() == FunctionLayout::kImplicitSetter) || - (function.kind() == FunctionLayout::kImplicitStaticGetter) || - (function.kind() == FunctionLayout::kMethodExtractor) || - (function.kind() == FunctionLayout::kInvokeFieldDispatcher) || - (function.kind() == FunctionLayout::kNoSuchMethodDispatcher)); - ParseKernelASTFunction(); switch (function.kind()) { @@ -3174,8 +3120,6 @@ Fragment StreamingFlowGraphBuilder::BuildStaticInvocation(TokenPosition* p) { NULL)); // Special case identical(x, y) call. - // Note: similar optimization is performed in bytecode flow graph builder - - // see BytecodeFlowGraphBuilder::BuildDirectCall(). // TODO(27590) consider moving this into the inliner and force inline it // there. if (special_case_identical) { diff --git a/runtime/vm/compiler/frontend/kernel_binary_flowgraph.h b/runtime/vm/compiler/frontend/kernel_binary_flowgraph.h index ebaa6fb189c..ef94bf30b28 100644 --- a/runtime/vm/compiler/frontend/kernel_binary_flowgraph.h +++ b/runtime/vm/compiler/frontend/kernel_binary_flowgraph.h @@ -9,7 +9,6 @@ #error "AOT runtime should not use compiler sources (including header files)" #endif // defined(DART_PRECOMPILED_RUNTIME) -#include "vm/compiler/frontend/bytecode_reader.h" #include "vm/compiler/frontend/constant_reader.h" #include "vm/compiler/frontend/kernel_to_il.h" #include "vm/compiler/frontend/kernel_translation_helper.h" @@ -41,7 +40,6 @@ class StreamingFlowGraphBuilder : public KernelReaderHelper { &constant_reader_, active_class_, /* finalize= */ true), - bytecode_metadata_helper_(this, active_class_), direct_call_metadata_helper_(this), inferred_type_metadata_helper_(this, &constant_reader_), procedure_attributes_metadata_helper_(this), @@ -413,7 +411,6 @@ class StreamingFlowGraphBuilder : public KernelReaderHelper { ActiveClass* const active_class_; ConstantReader constant_reader_; TypeTranslator type_translator_; - BytecodeMetadataHelper bytecode_metadata_helper_; DirectCallMetadataHelper direct_call_metadata_helper_; InferredTypeMetadataHelper inferred_type_metadata_helper_; ProcedureAttributesMetadataHelper procedure_attributes_metadata_helper_; diff --git a/runtime/vm/compiler/frontend/kernel_to_il.cc b/runtime/vm/compiler/frontend/kernel_to_il.cc index 4e9d36ea696..7bcb54ac7b0 100644 --- a/runtime/vm/compiler/frontend/kernel_to_il.cc +++ b/runtime/vm/compiler/frontend/kernel_to_il.cc @@ -743,15 +743,9 @@ FlowGraph* FlowGraphBuilder::BuildGraph() { info.potential_natives() == GrowableObjectArray::null()); #endif - auto& kernel_data = ExternalTypedData::Handle(Z); - intptr_t kernel_data_program_offset = 0; - if (!function.is_declared_in_bytecode()) { - kernel_data = function.KernelData(); - kernel_data_program_offset = function.KernelDataProgramOffset(); - } + auto& kernel_data = ExternalTypedData::Handle(Z, function.KernelData()); + intptr_t kernel_data_program_offset = function.KernelDataProgramOffset(); - // TODO(alexmarkov): refactor this - StreamingFlowGraphBuilder should not be - // used for bytecode functions. StreamingFlowGraphBuilder streaming_flow_graph_builder( this, kernel_data, kernel_data_program_offset); return streaming_flow_graph_builder.BuildGraph(); @@ -837,11 +831,6 @@ bool FlowGraphBuilder::IsRecognizedMethodForFlowGraph( case MethodRecognizer::kFfiStorePointer: case MethodRecognizer::kFfiFromAddress: case MethodRecognizer::kFfiGetAddress: - // This list must be kept in sync with BytecodeReaderHelper::NativeEntry in - // runtime/vm/compiler/frontend/bytecode_reader.cc and implemented in the - // bytecode interpreter in runtime/vm/interpreter.cc. Alternatively, these - // methods must work in their original form (a Dart body or native entry) in - // the bytecode interpreter. case MethodRecognizer::kObjectEquals: case MethodRecognizer::kStringBaseLength: case MethodRecognizer::kStringBaseIsEmpty: diff --git a/runtime/vm/compiler/frontend/kernel_translation_helper.cc b/runtime/vm/compiler/frontend/kernel_translation_helper.cc index 59d6362eaa5..05e62eb67c8 100644 --- a/runtime/vm/compiler/frontend/kernel_translation_helper.cc +++ b/runtime/vm/compiler/frontend/kernel_translation_helper.cc @@ -578,9 +578,6 @@ ClassPtr TranslationHelper::LookupClassByKernelClass(NameIndex kernel_class) { Class::Handle(Z, library.LookupClassAllowPrivate(class_name)); CheckStaticLookup(klass); ASSERT(!klass.IsNull()); - if (klass.is_declared_in_bytecode()) { - klass.EnsureDeclarationLoaded(); - } name_index_handle_ = Smi::New(kernel_class); return info_.InsertClass(thread_, name_index_handle_, klass); } @@ -2982,9 +2979,6 @@ void TypeTranslator::BuildInterfaceType(bool simple) { const Class& klass = Class::Handle(Z, H.LookupClassByKernelClass(klass_name)); ASSERT(!klass.IsNull()); - if (klass.is_declared_in_bytecode()) { - klass.EnsureDeclarationLoaded(); - } if (simple) { if (finalize_ || klass.is_type_finalized()) { // Fast path for non-generic types: retrieve or populate the class's only diff --git a/runtime/vm/compiler/frontend/kernel_translation_helper.h b/runtime/vm/compiler/frontend/kernel_translation_helper.h index e3f6c542317..4dfed5a8546 100644 --- a/runtime/vm/compiler/frontend/kernel_translation_helper.h +++ b/runtime/vm/compiler/frontend/kernel_translation_helper.h @@ -194,11 +194,6 @@ class TranslationHelper { const char* format, ...) PRINTF_ATTRIBUTE(5, 6); - ArrayPtr GetBytecodeComponent() const { return info_.bytecode_component(); } - void SetBytecodeComponent(const Array& bytecode_component) { - info_.set_bytecode_component(bytecode_component); - } - void SetExpressionEvaluationFunction(const Function& function) { ASSERT(expression_evaluation_function_ == nullptr); expression_evaluation_function_ = &Function::Handle(zone_, function.raw()); @@ -1260,8 +1255,6 @@ class KernelReaderHelper { // kernel program. intptr_t data_program_offset_; - friend class BytecodeMetadataHelper; - friend class BytecodeReaderHelper; friend class ClassHelper; friend class CallSiteAttributesMetadataHelper; friend class ConstantReader; diff --git a/runtime/vm/compiler/frontend/scope_builder.cc b/runtime/vm/compiler/frontend/scope_builder.cc index c9a54fdb664..2cf2c296401 100644 --- a/runtime/vm/compiler/frontend/scope_builder.cc +++ b/runtime/vm/compiler/frontend/scope_builder.cc @@ -20,7 +20,7 @@ namespace kernel { bool MethodCanSkipTypeChecksForNonCovariantTypeArguments( const Function& method) { // Dart 2 type system at non-dynamic call sites statically guarantees that - // argument values match declarated parameter types for all non-covariant + // argument values match declared parameter types for all non-covariant // and non-generic-covariant parameters. The same applies to type parameters // bounds for type parameters of generic functions. // @@ -29,12 +29,7 @@ bool MethodCanSkipTypeChecksForNonCovariantTypeArguments( // // Though for some kinds of methods (e.g. ffi trampolines called from native // code) we do have to perform type checks for all parameters. - // - // TODO(dartbug.com/40813): Remove the closure case when argument checks have - // been fully moved out of closures. - return !method.CanReceiveDynamicInvocation() && - !(method.IsClosureFunction() && - Function::ClosureBodiesContainNonCovariantTypeArgumentChecks()); + return !method.CanReceiveDynamicInvocation(); } // Returns true if the given method can skip type checks for all arguments diff --git a/runtime/vm/compiler/jit/compiler.cc b/runtime/vm/compiler/jit/compiler.cc index 2657e52b576..e122c5fc925 100644 --- a/runtime/vm/compiler/jit/compiler.cc +++ b/runtime/vm/compiler/jit/compiler.cc @@ -22,7 +22,6 @@ #include "vm/compiler/cha.h" #include "vm/compiler/compiler_pass.h" #include "vm/compiler/compiler_state.h" -#include "vm/compiler/frontend/bytecode_reader.h" #include "vm/compiler/frontend/flow_graph_builder.h" #include "vm/compiler/frontend/kernel_to_il.h" #include "vm/compiler/jit/jit_call_specializer.h" @@ -84,7 +83,6 @@ DEFINE_FLAG(bool, "Trace only optimizing compiler operations."); DEFINE_FLAG(bool, trace_bailout, false, "Print bailout from ssa compiler."); -DECLARE_FLAG(bool, enable_interpreter); DECLARE_FLAG(bool, huge_method_cutoff_in_code_size); DECLARE_FLAG(bool, trace_failed_optimization_attempts); @@ -215,25 +213,7 @@ DEFINE_RUNTIME_ENTRY(CompileFunction, 1) { ASSERT(thread->IsMutatorThread()); const Function& function = Function::CheckedHandle(zone, arguments.ArgAt(0)); Object& result = Object::Handle(zone); - - if (FLAG_enable_interpreter && function.IsBytecodeAllowed(zone)) { - if (!function.HasBytecode()) { - result = kernel::BytecodeReader::ReadFunctionBytecode(thread, function); - if (!result.IsNull()) { - Exceptions::PropagateError(Error::Cast(result)); - } - } - if (function.HasBytecode() && (FLAG_compilation_counter_threshold != 0)) { - // If interpreter is enabled and there is bytecode, LazyCompile stub - // (which calls CompileFunction) should proceed to InterpretCall in order - // to enter interpreter. In such case, compilation is postponed and - // triggered by interpreter later via CompileInterpretedFunction. - return; - } - // Fall back to compilation. - } else { - ASSERT(!function.HasCode()); - } + ASSERT(!function.HasCode()); result = Compiler::CompileFunction(thread, function); if (result.IsError()) { @@ -495,13 +475,6 @@ void CompileParsedFunctionHelper::CheckIfBackgroundCompilerIsBeingStopped( Compiler::AbortBackgroundCompilation( DeoptId::kNone, "Optimizing Background compilation is being stopped"); } - } else { - if (FLAG_enable_interpreter && - !isolate()->background_compiler()->is_running()) { - // The background compiler is being stopped. - Compiler::AbortBackgroundCompilation( - DeoptId::kNone, "Background compilation is being stopped"); - } } } @@ -783,9 +756,8 @@ static ObjectPtr CompileFunctionHelper(CompilationPipeline* pipeline, function.set_is_background_optimizable(false); // Trigger another optimization soon on the main thread. - function.SetUsageCounter(optimized - ? FLAG_optimization_counter_threshold - : FLAG_compilation_counter_threshold); + function.SetUsageCounter( + optimized ? FLAG_optimization_counter_threshold : 0); return Error::null(); } else if (error.IsLanguageError() && LanguageError::Cast(error).kind() == Report::kBailout) { @@ -942,8 +914,6 @@ ObjectPtr Compiler::CompileOptimizedFunction(Thread* thread, TIMELINE_FUNCTION_COMPILATION_DURATION(thread, event_name, function); #endif // defined(SUPPORT_TIMELINE) - ASSERT(function.ShouldCompilerOptimize()); - CompilationPipeline* pipeline = CompilationPipeline::New(thread->zone(), function); return CompileFunctionHelper(pipeline, function, /* optimized = */ true, @@ -978,21 +948,8 @@ void Compiler::ComputeLocalVarDescriptors(const Code& code) { auto& var_descs = LocalVarDescriptors::Handle(zone); - if (function.is_declared_in_bytecode()) { - if (function.HasBytecode()) { - const auto& bytecode = Bytecode::Handle(zone, function.bytecode()); - var_descs = bytecode.GetLocalVarDescriptors(); - LocalVarDescriptorsBuilder builder; - builder.AddDeoptIdToContextLevelMappings(context_level_array); - builder.AddAll(zone, var_descs); - var_descs = builder.Done(); - } else { - var_descs = Object::empty_var_descriptors().raw(); - } - } else { - var_descs = parsed_function->scope()->GetVarDescriptors( - function, context_level_array); - } + var_descs = parsed_function->scope()->GetVarDescriptors( + function, context_level_array); ASSERT(!var_descs.IsNull()); code.set_var_descriptors(var_descs); @@ -1026,30 +983,6 @@ ErrorPtr Compiler::CompileAllFunctions(const Class& cls) { return Error::null(); } -ErrorPtr Compiler::ReadAllBytecode(const Class& cls) { - Thread* thread = Thread::Current(); - ASSERT(thread->IsMutatorThread()); - Zone* zone = thread->zone(); - Error& error = Error::Handle(zone, cls.EnsureIsFinalized(thread)); - ASSERT(error.IsNull()); - Array& functions = Array::Handle(zone, cls.current_functions()); - Function& func = Function::Handle(zone); - // Compile all the regular functions. - for (int i = 0; i < functions.Length(); i++) { - func ^= functions.At(i); - ASSERT(!func.IsNull()); - if (func.IsBytecodeAllowed(zone) && !func.HasBytecode() && - !func.HasCode()) { - ErrorPtr error = - kernel::BytecodeReader::ReadFunctionBytecode(thread, func); - if (error != Error::null()) { - return error; - } - } - } - return Error::null(); -} - void Compiler::AbortBackgroundCompilation(intptr_t deopt_id, const char* msg) { if (FLAG_trace_compiler) { THR_Print("ABORT background compilation: %s\n", msg); @@ -1209,13 +1142,9 @@ void BackgroundCompiler::Run() { } } while (!function.IsNull()) { - if (is_optimizing()) { - Compiler::CompileOptimizedFunction(thread, function, - Compiler::kNoOSRDeoptId); - } else { - ASSERT(FLAG_enable_interpreter); - Compiler::CompileFunction(thread, function); - } + ASSERT(is_optimizing()); + Compiler::CompileOptimizedFunction(thread, function, + Compiler::kNoOSRDeoptId); QueueElement* qelem = NULL; { diff --git a/runtime/vm/compiler/jit/compiler.h b/runtime/vm/compiler/jit/compiler.h index 29029df06bb..75d59521617 100644 --- a/runtime/vm/compiler/jit/compiler.h +++ b/runtime/vm/compiler/jit/compiler.h @@ -84,8 +84,6 @@ class Compiler : public AllStatic { static ObjectPtr CompileFunction(Thread* thread, const Function& function); // Generates unoptimized code if not present, current code is unchanged. - // Bytecode is considered unoptimized code. - // TODO(regis): Revisit when deoptimizing mixed bytecode and jitted code. static ErrorPtr EnsureUnoptimizedCode(Thread* thread, const Function& function); @@ -108,9 +106,6 @@ class Compiler : public AllStatic { // Returns Error::null() if there is no compilation error. static ErrorPtr CompileAllFunctions(const Class& cls); - // Eagerly read all bytecode. - static ErrorPtr ReadAllBytecode(const Class& cls); - // Notify the compiler that background (optimized) compilation has failed // because the mutator thread changed the state (e.g., deoptimization, // deferred loading). The background compilation may retry to compile @@ -129,36 +124,24 @@ class BackgroundCompiler { static void Start(Isolate* isolate) { ASSERT(Thread::Current()->IsMutatorThread()); - if (FLAG_enable_interpreter && isolate->background_compiler() != NULL) { - isolate->background_compiler()->Start(); - } if (isolate->optimizing_background_compiler() != NULL) { isolate->optimizing_background_compiler()->Start(); } } static void Stop(Isolate* isolate) { ASSERT(Thread::Current()->IsMutatorThread()); - if (FLAG_enable_interpreter && isolate->background_compiler() != NULL) { - isolate->background_compiler()->Stop(); - } if (isolate->optimizing_background_compiler() != NULL) { isolate->optimizing_background_compiler()->Stop(); } } static void Enable(Isolate* isolate) { ASSERT(Thread::Current()->IsMutatorThread()); - if (FLAG_enable_interpreter && isolate->background_compiler() != NULL) { - isolate->background_compiler()->Enable(); - } if (isolate->optimizing_background_compiler() != NULL) { isolate->optimizing_background_compiler()->Enable(); } } static void Disable(Isolate* isolate) { ASSERT(Thread::Current()->IsMutatorThread()); - if (FLAG_enable_interpreter && isolate->background_compiler() != NULL) { - isolate->background_compiler()->Disable(); - } if (isolate->optimizing_background_compiler() != NULL) { isolate->optimizing_background_compiler()->Disable(); } @@ -169,10 +152,6 @@ class BackgroundCompiler { if (isolate->optimizing_background_compiler() != NULL) { return isolate->optimizing_background_compiler()->IsDisabled(); } - } else { - if (FLAG_enable_interpreter && isolate->background_compiler() != NULL) { - return isolate->background_compiler()->IsDisabled(); - } } return false; } diff --git a/runtime/vm/compiler/runtime_api.cc b/runtime/vm/compiler/runtime_api.cc index e83406a45ed..223c76d93a5 100644 --- a/runtime/vm/compiler/runtime_api.cc +++ b/runtime/vm/compiler/runtime_api.cc @@ -727,8 +727,8 @@ uword Thread::vm_execution_state() { return dart::Thread::ExecutionState::kThreadInVM; } -uword Thread::vm_tag_compiled_id() { - return dart::VMTag::kDartCompiledTagId; +uword Thread::vm_tag_dart_id() { + return dart::VMTag::kDartTagId; } uword Thread::exit_through_runtime_call() { @@ -998,10 +998,6 @@ word KernelProgramInfo::NextFieldOffset() { return -kWordSize; } -word Bytecode::NextFieldOffset() { - return -kWordSize; -} - word PcDescriptors::NextFieldOffset() { return -kWordSize; } @@ -1026,10 +1022,6 @@ word ContextScope::NextFieldOffset() { return -kWordSize; } -word ParameterTypeCheck::NextFieldOffset() { - return -kWordSize; -} - word UnlinkedCall::NextFieldOffset() { return -kWordSize; } diff --git a/runtime/vm/compiler/runtime_api.h b/runtime/vm/compiler/runtime_api.h index a7e95472190..4f53edad82e 100644 --- a/runtime/vm/compiler/runtime_api.h +++ b/runtime/vm/compiler/runtime_api.h @@ -807,12 +807,6 @@ class KernelProgramInfo : public AllStatic { static word NextFieldOffset(); }; -class Bytecode : public AllStatic { - public: - static word InstanceSize(); - static word NextFieldOffset(); -}; - class PcDescriptors : public AllStatic { public: static word HeaderSize(); @@ -855,12 +849,6 @@ class ContextScope : public AllStatic { static word NextFieldOffset(); }; -class ParameterTypeCheck : public AllStatic { - public: - static word InstanceSize(); - static word NextFieldOffset(); -}; - class UnlinkedCall : public AllStatic { public: static word InstanceSize(); @@ -1037,7 +1025,7 @@ class Thread : public AllStatic { static word slow_type_test_entry_point_offset(); static word write_barrier_entry_point_offset(); static word vm_tag_offset(); - static uword vm_tag_compiled_id(); + static uword vm_tag_dart_id(); static word safepoint_state_offset(); static uword safepoint_state_unacquired(); @@ -1067,8 +1055,6 @@ class Thread : public AllStatic { static word slow_type_test_stub_offset(); static word call_to_runtime_stub_offset(); static word invoke_dart_code_stub_offset(); - static word interpret_call_entry_point_offset(); - static word invoke_dart_code_from_bytecode_stub_offset(); static word late_initialization_error_shared_without_fpu_regs_stub_offset(); static word late_initialization_error_shared_with_fpu_regs_stub_offset(); static word null_error_shared_without_fpu_regs_stub_offset(); diff --git a/runtime/vm/compiler/runtime_offsets_extracted.h b/runtime/vm/compiler/runtime_offsets_extracted.h index bd58afd5f31..6650cd6945d 100644 --- a/runtime/vm/compiler/runtime_offsets_extracted.h +++ b/runtime/vm/compiler/runtime_offsets_extracted.h @@ -19,7 +19,7 @@ #if defined(TARGET_ARCH_ARM) static constexpr dart::compiler::target::word Function_usage_counter_offset = - 76; + 84; static constexpr dart::compiler::target::word ICData_receivers_static_type_offset = 16; static constexpr dart::compiler::target::word ObjectPool_elements_start_offset = @@ -133,9 +133,9 @@ static constexpr dart::compiler::target::word Function_code_offset = 44; static constexpr dart::compiler::target::word Function_data_offset = 36; static constexpr dart::compiler::target::word Function_entry_point_offset[] = { 4, 8}; -static constexpr dart::compiler::target::word Function_kind_tag_offset = 64; +static constexpr dart::compiler::target::word Function_kind_tag_offset = 72; static constexpr dart::compiler::target::word Function_packed_fields_offset = - 68; + 76; static constexpr dart::compiler::target::word Function_parameter_names_offset = 28; static constexpr dart::compiler::target::word Function_parameter_types_offset = @@ -217,159 +217,155 @@ static constexpr dart::compiler::target::word String_hash_offset = 8; static constexpr dart::compiler::target::word String_length_offset = 4; static constexpr dart::compiler::target::word SubtypeTestCache_cache_offset = 4; static constexpr dart::compiler::target::word - Thread_AllocateArray_entry_point_offset = 384; + Thread_AllocateArray_entry_point_offset = 376; static constexpr dart::compiler::target::word Thread_active_exception_offset = - 732; + 696; static constexpr dart::compiler::target::word Thread_active_stacktrace_offset = - 736; + 700; static constexpr dart::compiler::target::word Thread_array_write_barrier_code_offset = 128; static constexpr dart::compiler::target::word - Thread_array_write_barrier_entry_point_offset = 276; + Thread_array_write_barrier_entry_point_offset = 272; static constexpr dart::compiler::target::word - Thread_allocate_mint_with_fpu_regs_entry_point_offset = 284; + Thread_allocate_mint_with_fpu_regs_entry_point_offset = 280; static constexpr dart::compiler::target::word - Thread_allocate_mint_with_fpu_regs_stub_offset = 192; + Thread_allocate_mint_with_fpu_regs_stub_offset = 188; static constexpr dart::compiler::target::word - Thread_allocate_mint_without_fpu_regs_entry_point_offset = 288; + Thread_allocate_mint_without_fpu_regs_entry_point_offset = 284; static constexpr dart::compiler::target::word - Thread_allocate_mint_without_fpu_regs_stub_offset = 196; + Thread_allocate_mint_without_fpu_regs_stub_offset = 192; static constexpr dart::compiler::target::word - Thread_allocate_object_entry_point_offset = 292; + Thread_allocate_object_entry_point_offset = 288; static constexpr dart::compiler::target::word - Thread_allocate_object_stub_offset = 200; + Thread_allocate_object_stub_offset = 196; static constexpr dart::compiler::target::word - Thread_allocate_object_parameterized_entry_point_offset = 296; + Thread_allocate_object_parameterized_entry_point_offset = 292; static constexpr dart::compiler::target::word - Thread_allocate_object_parameterized_stub_offset = 204; + Thread_allocate_object_parameterized_stub_offset = 200; static constexpr dart::compiler::target::word - Thread_allocate_object_slow_entry_point_offset = 300; + Thread_allocate_object_slow_entry_point_offset = 296; static constexpr dart::compiler::target::word - Thread_allocate_object_slow_stub_offset = 208; -static constexpr dart::compiler::target::word Thread_api_top_scope_offset = 768; + Thread_allocate_object_slow_stub_offset = 204; +static constexpr dart::compiler::target::word Thread_api_top_scope_offset = 732; static constexpr dart::compiler::target::word Thread_async_stack_trace_offset = 96; static constexpr dart::compiler::target::word - Thread_auto_scope_native_wrapper_entry_point_offset = 344; + Thread_auto_scope_native_wrapper_entry_point_offset = 340; static constexpr dart::compiler::target::word Thread_bool_false_offset = 120; static constexpr dart::compiler::target::word Thread_bool_true_offset = 116; static constexpr dart::compiler::target::word - Thread_bootstrap_native_wrapper_entry_point_offset = 336; + Thread_bootstrap_native_wrapper_entry_point_offset = 332; static constexpr dart::compiler::target::word - Thread_call_to_runtime_entry_point_offset = 280; + Thread_call_to_runtime_entry_point_offset = 276; static constexpr dart::compiler::target::word - Thread_call_to_runtime_stub_offset = 148; -static constexpr dart::compiler::target::word Thread_dart_stream_offset = 776; + Thread_call_to_runtime_stub_offset = 144; +static constexpr dart::compiler::target::word Thread_dart_stream_offset = 740; static constexpr dart::compiler::target::word Thread_dispatch_table_array_offset = 48; static constexpr dart::compiler::target::word Thread_optimize_entry_offset = - 320; -static constexpr dart::compiler::target::word Thread_optimize_stub_offset = 236; + 316; +static constexpr dart::compiler::target::word Thread_optimize_stub_offset = 232; static constexpr dart::compiler::target::word Thread_deoptimize_entry_offset = - 324; + 320; static constexpr dart::compiler::target::word Thread_deoptimize_stub_offset = - 240; + 236; static constexpr dart::compiler::target::word Thread_double_abs_address_offset = - 364; + 356; static constexpr dart::compiler::target::word - Thread_double_negate_address_offset = 360; + Thread_double_negate_address_offset = 352; static constexpr dart::compiler::target::word Thread_end_offset = 56; static constexpr dart::compiler::target::word - Thread_enter_safepoint_stub_offset = 260; + Thread_enter_safepoint_stub_offset = 256; static constexpr dart::compiler::target::word Thread_execution_state_offset = - 752; + 716; static constexpr dart::compiler::target::word - Thread_exit_safepoint_stub_offset = 264; + Thread_exit_safepoint_stub_offset = 260; static constexpr dart::compiler::target::word - Thread_call_native_through_safepoint_stub_offset = 268; + Thread_call_native_through_safepoint_stub_offset = 264; static constexpr dart::compiler::target::word - Thread_call_native_through_safepoint_entry_point_offset = 328; + Thread_call_native_through_safepoint_entry_point_offset = 324; static constexpr dart::compiler::target::word Thread_fix_allocation_stub_code_offset = 136; static constexpr dart::compiler::target::word Thread_fix_callers_target_code_offset = 132; static constexpr dart::compiler::target::word - Thread_float_absolute_address_offset = 376; + Thread_float_absolute_address_offset = 368; static constexpr dart::compiler::target::word - Thread_float_negate_address_offset = 372; + Thread_float_negate_address_offset = 364; static constexpr dart::compiler::target::word Thread_float_not_address_offset = - 368; + 360; static constexpr dart::compiler::target::word - Thread_float_zerow_address_offset = 380; + Thread_float_zerow_address_offset = 372; static constexpr dart::compiler::target::word Thread_global_object_pool_offset = - 740; -static constexpr dart::compiler::target::word - Thread_interpret_call_entry_point_offset = 348; -static constexpr dart::compiler::target::word - Thread_invoke_dart_code_from_bytecode_stub_offset = 144; + 704; static constexpr dart::compiler::target::word Thread_invoke_dart_code_stub_offset = 140; static constexpr dart::compiler::target::word Thread_exit_through_ffi_offset = - 764; + 728; static constexpr dart::compiler::target::word Thread_isolate_offset = 44; static constexpr dart::compiler::target::word Thread_field_table_values_offset = 68; static constexpr dart::compiler::target::word - Thread_lazy_deopt_from_return_stub_offset = 244; + Thread_lazy_deopt_from_return_stub_offset = 240; static constexpr dart::compiler::target::word - Thread_lazy_deopt_from_throw_stub_offset = 248; + Thread_lazy_deopt_from_throw_stub_offset = 244; static constexpr dart::compiler::target::word - Thread_lazy_specialize_type_test_stub_offset = 256; + Thread_lazy_specialize_type_test_stub_offset = 252; static constexpr dart::compiler::target::word Thread_marking_stack_block_offset = 84; static constexpr dart::compiler::target::word - Thread_megamorphic_call_checked_entry_offset = 312; + Thread_megamorphic_call_checked_entry_offset = 308; static constexpr dart::compiler::target::word - Thread_switchable_call_miss_entry_offset = 316; + Thread_switchable_call_miss_entry_offset = 312; static constexpr dart::compiler::target::word - Thread_switchable_call_miss_stub_offset = 220; + Thread_switchable_call_miss_stub_offset = 216; static constexpr dart::compiler::target::word - Thread_no_scope_native_wrapper_entry_point_offset = 340; + Thread_no_scope_native_wrapper_entry_point_offset = 336; static constexpr dart::compiler::target::word - Thread_late_initialization_error_shared_with_fpu_regs_stub_offset = 156; + Thread_late_initialization_error_shared_with_fpu_regs_stub_offset = 152; static constexpr dart::compiler::target::word - Thread_late_initialization_error_shared_without_fpu_regs_stub_offset = 152; + Thread_late_initialization_error_shared_without_fpu_regs_stub_offset = 148; static constexpr dart::compiler::target::word - Thread_null_error_shared_with_fpu_regs_stub_offset = 164; + Thread_null_error_shared_with_fpu_regs_stub_offset = 160; static constexpr dart::compiler::target::word - Thread_null_error_shared_without_fpu_regs_stub_offset = 160; + Thread_null_error_shared_without_fpu_regs_stub_offset = 156; static constexpr dart::compiler::target::word - Thread_null_arg_error_shared_with_fpu_regs_stub_offset = 172; + Thread_null_arg_error_shared_with_fpu_regs_stub_offset = 168; static constexpr dart::compiler::target::word - Thread_null_arg_error_shared_without_fpu_regs_stub_offset = 168; + Thread_null_arg_error_shared_without_fpu_regs_stub_offset = 164; static constexpr dart::compiler::target::word - Thread_null_cast_error_shared_with_fpu_regs_stub_offset = 180; + Thread_null_cast_error_shared_with_fpu_regs_stub_offset = 176; static constexpr dart::compiler::target::word - Thread_null_cast_error_shared_without_fpu_regs_stub_offset = 176; + Thread_null_cast_error_shared_without_fpu_regs_stub_offset = 172; static constexpr dart::compiler::target::word - Thread_range_error_shared_with_fpu_regs_stub_offset = 188; + Thread_range_error_shared_with_fpu_regs_stub_offset = 184; static constexpr dart::compiler::target::word - Thread_range_error_shared_without_fpu_regs_stub_offset = 184; + Thread_range_error_shared_without_fpu_regs_stub_offset = 180; static constexpr dart::compiler::target::word Thread_object_null_offset = 112; static constexpr dart::compiler::target::word - Thread_predefined_symbols_address_offset = 352; -static constexpr dart::compiler::target::word Thread_resume_pc_offset = 744; + Thread_predefined_symbols_address_offset = 344; +static constexpr dart::compiler::target::word Thread_resume_pc_offset = 708; static constexpr dart::compiler::target::word - Thread_saved_shadow_call_stack_offset = 748; + Thread_saved_shadow_call_stack_offset = 712; static constexpr dart::compiler::target::word Thread_safepoint_state_offset = - 756; + 720; static constexpr dart::compiler::target::word - Thread_slow_type_test_stub_offset = 252; + Thread_slow_type_test_stub_offset = 248; static constexpr dart::compiler::target::word - Thread_slow_type_test_entry_point_offset = 332; + Thread_slow_type_test_entry_point_offset = 328; static constexpr dart::compiler::target::word Thread_stack_limit_offset = 36; static constexpr dart::compiler::target::word Thread_saved_stack_limit_offset = 60; static constexpr dart::compiler::target::word Thread_stack_overflow_flags_offset = 64; static constexpr dart::compiler::target::word - Thread_stack_overflow_shared_with_fpu_regs_entry_point_offset = 308; + Thread_stack_overflow_shared_with_fpu_regs_entry_point_offset = 304; static constexpr dart::compiler::target::word - Thread_stack_overflow_shared_with_fpu_regs_stub_offset = 216; + Thread_stack_overflow_shared_with_fpu_regs_stub_offset = 212; static constexpr dart::compiler::target::word - Thread_stack_overflow_shared_without_fpu_regs_entry_point_offset = 304; + Thread_stack_overflow_shared_without_fpu_regs_entry_point_offset = 300; static constexpr dart::compiler::target::word - Thread_stack_overflow_shared_without_fpu_regs_stub_offset = 212; + Thread_stack_overflow_shared_without_fpu_regs_stub_offset = 208; static constexpr dart::compiler::target::word Thread_store_buffer_block_offset = 80; static constexpr dart::compiler::target::word @@ -382,10 +378,10 @@ static constexpr dart::compiler::target::word Thread_vm_tag_offset = 92; static constexpr dart::compiler::target::word Thread_write_barrier_code_offset = 124; static constexpr dart::compiler::target::word - Thread_write_barrier_entry_point_offset = 272; + Thread_write_barrier_entry_point_offset = 268; static constexpr dart::compiler::target::word Thread_write_barrier_mask_offset = 40; -static constexpr dart::compiler::target::word Thread_callback_code_offset = 760; +static constexpr dart::compiler::target::word Thread_callback_code_offset = 724; static constexpr dart::compiler::target::word TimelineStream_enabled_offset = 8; static constexpr dart::compiler::target::word TwoByteString_data_offset = 12; static constexpr dart::compiler::target::word Type_arguments_offset = 16; @@ -435,12 +431,11 @@ static constexpr dart::compiler::target::word Code_entry_point_offset[] = { 4, 12, 8, 16}; static constexpr dart::compiler::target::word Thread_write_barrier_wrappers_thread_offset[] = { - 700, 704, 708, 712, 716, -1, 720, -1, 724, 728, -1, -1, -1, -1, -1, -1}; + 664, 668, 672, 676, 680, -1, 684, -1, 688, 692, -1, -1, -1, -1, -1, -1}; static constexpr dart::compiler::target::word ApiError_InstanceSize = 8; static constexpr dart::compiler::target::word Array_InstanceSize = 12; static constexpr dart::compiler::target::word Array_header_size = 12; static constexpr dart::compiler::target::word Bool_InstanceSize = 8; -static constexpr dart::compiler::target::word Bytecode_InstanceSize = 48; static constexpr dart::compiler::target::word Capability_InstanceSize = 16; static constexpr dart::compiler::target::word Class_InstanceSize = 128; static constexpr dart::compiler::target::word Closure_InstanceSize = 28; @@ -480,7 +475,7 @@ static constexpr dart::compiler::target::word static constexpr dart::compiler::target::word Int32x4_InstanceSize = 24; static constexpr dart::compiler::target::word Integer_InstanceSize = 4; static constexpr dart::compiler::target::word KernelProgramInfo_InstanceSize = - 64; + 60; static constexpr dart::compiler::target::word LanguageError_InstanceSize = 28; static constexpr dart::compiler::target::word Library_InstanceSize = 84; static constexpr dart::compiler::target::word LibraryPrefix_InstanceSize = 20; @@ -499,8 +494,6 @@ static constexpr dart::compiler::target::word Number_InstanceSize = 4; static constexpr dart::compiler::target::word Object_InstanceSize = 4; static constexpr dart::compiler::target::word ObjectPool_InstanceSize = 8; static constexpr dart::compiler::target::word OneByteString_InstanceSize = 12; -static constexpr dart::compiler::target::word ParameterTypeCheck_InstanceSize = - 24; static constexpr dart::compiler::target::word PatchClass_InstanceSize = 24; static constexpr dart::compiler::target::word PcDescriptors_HeaderSize = 8; static constexpr dart::compiler::target::word Pointer_InstanceSize = 12; @@ -740,160 +733,156 @@ static constexpr dart::compiler::target::word String_hash_offset = 4; static constexpr dart::compiler::target::word String_length_offset = 8; static constexpr dart::compiler::target::word SubtypeTestCache_cache_offset = 8; static constexpr dart::compiler::target::word - Thread_AllocateArray_entry_point_offset = 752; + Thread_AllocateArray_entry_point_offset = 736; static constexpr dart::compiler::target::word Thread_active_exception_offset = - 1472; + 1400; static constexpr dart::compiler::target::word Thread_active_stacktrace_offset = - 1480; + 1408; static constexpr dart::compiler::target::word Thread_array_write_barrier_code_offset = 240; static constexpr dart::compiler::target::word - Thread_array_write_barrier_entry_point_offset = 536; + Thread_array_write_barrier_entry_point_offset = 528; static constexpr dart::compiler::target::word - Thread_allocate_mint_with_fpu_regs_entry_point_offset = 552; + Thread_allocate_mint_with_fpu_regs_entry_point_offset = 544; static constexpr dart::compiler::target::word - Thread_allocate_mint_with_fpu_regs_stub_offset = 368; + Thread_allocate_mint_with_fpu_regs_stub_offset = 360; static constexpr dart::compiler::target::word - Thread_allocate_mint_without_fpu_regs_entry_point_offset = 560; + Thread_allocate_mint_without_fpu_regs_entry_point_offset = 552; static constexpr dart::compiler::target::word - Thread_allocate_mint_without_fpu_regs_stub_offset = 376; + Thread_allocate_mint_without_fpu_regs_stub_offset = 368; static constexpr dart::compiler::target::word - Thread_allocate_object_entry_point_offset = 568; + Thread_allocate_object_entry_point_offset = 560; static constexpr dart::compiler::target::word - Thread_allocate_object_stub_offset = 384; + Thread_allocate_object_stub_offset = 376; static constexpr dart::compiler::target::word - Thread_allocate_object_parameterized_entry_point_offset = 576; + Thread_allocate_object_parameterized_entry_point_offset = 568; static constexpr dart::compiler::target::word - Thread_allocate_object_parameterized_stub_offset = 392; + Thread_allocate_object_parameterized_stub_offset = 384; static constexpr dart::compiler::target::word - Thread_allocate_object_slow_entry_point_offset = 584; + Thread_allocate_object_slow_entry_point_offset = 576; static constexpr dart::compiler::target::word - Thread_allocate_object_slow_stub_offset = 400; + Thread_allocate_object_slow_stub_offset = 392; static constexpr dart::compiler::target::word Thread_api_top_scope_offset = - 1544; + 1472; static constexpr dart::compiler::target::word Thread_async_stack_trace_offset = 192; static constexpr dart::compiler::target::word - Thread_auto_scope_native_wrapper_entry_point_offset = 672; + Thread_auto_scope_native_wrapper_entry_point_offset = 664; static constexpr dart::compiler::target::word Thread_bool_false_offset = 224; static constexpr dart::compiler::target::word Thread_bool_true_offset = 216; static constexpr dart::compiler::target::word - Thread_bootstrap_native_wrapper_entry_point_offset = 656; + Thread_bootstrap_native_wrapper_entry_point_offset = 648; static constexpr dart::compiler::target::word - Thread_call_to_runtime_entry_point_offset = 544; + Thread_call_to_runtime_entry_point_offset = 536; static constexpr dart::compiler::target::word - Thread_call_to_runtime_stub_offset = 280; -static constexpr dart::compiler::target::word Thread_dart_stream_offset = 1560; + Thread_call_to_runtime_stub_offset = 272; +static constexpr dart::compiler::target::word Thread_dart_stream_offset = 1488; static constexpr dart::compiler::target::word Thread_dispatch_table_array_offset = 96; static constexpr dart::compiler::target::word Thread_optimize_entry_offset = - 624; -static constexpr dart::compiler::target::word Thread_optimize_stub_offset = 456; + 616; +static constexpr dart::compiler::target::word Thread_optimize_stub_offset = 448; static constexpr dart::compiler::target::word Thread_deoptimize_entry_offset = - 632; + 624; static constexpr dart::compiler::target::word Thread_deoptimize_stub_offset = - 464; + 456; static constexpr dart::compiler::target::word Thread_double_abs_address_offset = - 712; + 696; static constexpr dart::compiler::target::word - Thread_double_negate_address_offset = 704; + Thread_double_negate_address_offset = 688; static constexpr dart::compiler::target::word Thread_end_offset = 112; static constexpr dart::compiler::target::word - Thread_enter_safepoint_stub_offset = 504; + Thread_enter_safepoint_stub_offset = 496; static constexpr dart::compiler::target::word Thread_execution_state_offset = - 1512; + 1440; static constexpr dart::compiler::target::word - Thread_exit_safepoint_stub_offset = 512; + Thread_exit_safepoint_stub_offset = 504; static constexpr dart::compiler::target::word - Thread_call_native_through_safepoint_stub_offset = 520; + Thread_call_native_through_safepoint_stub_offset = 512; static constexpr dart::compiler::target::word - Thread_call_native_through_safepoint_entry_point_offset = 640; + Thread_call_native_through_safepoint_entry_point_offset = 632; static constexpr dart::compiler::target::word Thread_fix_allocation_stub_code_offset = 256; static constexpr dart::compiler::target::word Thread_fix_callers_target_code_offset = 248; static constexpr dart::compiler::target::word - Thread_float_absolute_address_offset = 736; + Thread_float_absolute_address_offset = 720; static constexpr dart::compiler::target::word - Thread_float_negate_address_offset = 728; + Thread_float_negate_address_offset = 712; static constexpr dart::compiler::target::word Thread_float_not_address_offset = - 720; + 704; static constexpr dart::compiler::target::word - Thread_float_zerow_address_offset = 744; + Thread_float_zerow_address_offset = 728; static constexpr dart::compiler::target::word Thread_global_object_pool_offset = - 1488; -static constexpr dart::compiler::target::word - Thread_interpret_call_entry_point_offset = 680; -static constexpr dart::compiler::target::word - Thread_invoke_dart_code_from_bytecode_stub_offset = 272; + 1416; static constexpr dart::compiler::target::word Thread_invoke_dart_code_stub_offset = 264; static constexpr dart::compiler::target::word Thread_exit_through_ffi_offset = - 1536; + 1464; static constexpr dart::compiler::target::word Thread_isolate_offset = 88; static constexpr dart::compiler::target::word Thread_field_table_values_offset = 136; static constexpr dart::compiler::target::word - Thread_lazy_deopt_from_return_stub_offset = 472; + Thread_lazy_deopt_from_return_stub_offset = 464; static constexpr dart::compiler::target::word - Thread_lazy_deopt_from_throw_stub_offset = 480; + Thread_lazy_deopt_from_throw_stub_offset = 472; static constexpr dart::compiler::target::word - Thread_lazy_specialize_type_test_stub_offset = 496; + Thread_lazy_specialize_type_test_stub_offset = 488; static constexpr dart::compiler::target::word Thread_marking_stack_block_offset = 168; static constexpr dart::compiler::target::word - Thread_megamorphic_call_checked_entry_offset = 608; + Thread_megamorphic_call_checked_entry_offset = 600; static constexpr dart::compiler::target::word - Thread_switchable_call_miss_entry_offset = 616; + Thread_switchable_call_miss_entry_offset = 608; static constexpr dart::compiler::target::word - Thread_switchable_call_miss_stub_offset = 424; + Thread_switchable_call_miss_stub_offset = 416; static constexpr dart::compiler::target::word - Thread_no_scope_native_wrapper_entry_point_offset = 664; + Thread_no_scope_native_wrapper_entry_point_offset = 656; static constexpr dart::compiler::target::word - Thread_late_initialization_error_shared_with_fpu_regs_stub_offset = 296; + Thread_late_initialization_error_shared_with_fpu_regs_stub_offset = 288; static constexpr dart::compiler::target::word - Thread_late_initialization_error_shared_without_fpu_regs_stub_offset = 288; + Thread_late_initialization_error_shared_without_fpu_regs_stub_offset = 280; static constexpr dart::compiler::target::word - Thread_null_error_shared_with_fpu_regs_stub_offset = 312; + Thread_null_error_shared_with_fpu_regs_stub_offset = 304; static constexpr dart::compiler::target::word - Thread_null_error_shared_without_fpu_regs_stub_offset = 304; + Thread_null_error_shared_without_fpu_regs_stub_offset = 296; static constexpr dart::compiler::target::word - Thread_null_arg_error_shared_with_fpu_regs_stub_offset = 328; + Thread_null_arg_error_shared_with_fpu_regs_stub_offset = 320; static constexpr dart::compiler::target::word - Thread_null_arg_error_shared_without_fpu_regs_stub_offset = 320; + Thread_null_arg_error_shared_without_fpu_regs_stub_offset = 312; static constexpr dart::compiler::target::word - Thread_null_cast_error_shared_with_fpu_regs_stub_offset = 344; + Thread_null_cast_error_shared_with_fpu_regs_stub_offset = 336; static constexpr dart::compiler::target::word - Thread_null_cast_error_shared_without_fpu_regs_stub_offset = 336; + Thread_null_cast_error_shared_without_fpu_regs_stub_offset = 328; static constexpr dart::compiler::target::word - Thread_range_error_shared_with_fpu_regs_stub_offset = 360; + Thread_range_error_shared_with_fpu_regs_stub_offset = 352; static constexpr dart::compiler::target::word - Thread_range_error_shared_without_fpu_regs_stub_offset = 352; + Thread_range_error_shared_without_fpu_regs_stub_offset = 344; static constexpr dart::compiler::target::word Thread_object_null_offset = 208; static constexpr dart::compiler::target::word - Thread_predefined_symbols_address_offset = 688; -static constexpr dart::compiler::target::word Thread_resume_pc_offset = 1496; + Thread_predefined_symbols_address_offset = 672; +static constexpr dart::compiler::target::word Thread_resume_pc_offset = 1424; static constexpr dart::compiler::target::word - Thread_saved_shadow_call_stack_offset = 1504; + Thread_saved_shadow_call_stack_offset = 1432; static constexpr dart::compiler::target::word Thread_safepoint_state_offset = - 1520; + 1448; static constexpr dart::compiler::target::word - Thread_slow_type_test_stub_offset = 488; + Thread_slow_type_test_stub_offset = 480; static constexpr dart::compiler::target::word - Thread_slow_type_test_entry_point_offset = 648; + Thread_slow_type_test_entry_point_offset = 640; static constexpr dart::compiler::target::word Thread_stack_limit_offset = 72; static constexpr dart::compiler::target::word Thread_saved_stack_limit_offset = 120; static constexpr dart::compiler::target::word Thread_stack_overflow_flags_offset = 128; static constexpr dart::compiler::target::word - Thread_stack_overflow_shared_with_fpu_regs_entry_point_offset = 600; + Thread_stack_overflow_shared_with_fpu_regs_entry_point_offset = 592; static constexpr dart::compiler::target::word - Thread_stack_overflow_shared_with_fpu_regs_stub_offset = 416; + Thread_stack_overflow_shared_with_fpu_regs_stub_offset = 408; static constexpr dart::compiler::target::word - Thread_stack_overflow_shared_without_fpu_regs_entry_point_offset = 592; + Thread_stack_overflow_shared_without_fpu_regs_entry_point_offset = 584; static constexpr dart::compiler::target::word - Thread_stack_overflow_shared_without_fpu_regs_stub_offset = 408; + Thread_stack_overflow_shared_without_fpu_regs_stub_offset = 400; static constexpr dart::compiler::target::word Thread_store_buffer_block_offset = 160; static constexpr dart::compiler::target::word @@ -906,11 +895,11 @@ static constexpr dart::compiler::target::word Thread_vm_tag_offset = 184; static constexpr dart::compiler::target::word Thread_write_barrier_code_offset = 232; static constexpr dart::compiler::target::word - Thread_write_barrier_entry_point_offset = 528; + Thread_write_barrier_entry_point_offset = 520; static constexpr dart::compiler::target::word Thread_write_barrier_mask_offset = 80; static constexpr dart::compiler::target::word Thread_callback_code_offset = - 1528; + 1456; static constexpr dart::compiler::target::word TimelineStream_enabled_offset = 16; static constexpr dart::compiler::target::word TwoByteString_data_offset = 16; @@ -961,13 +950,12 @@ static constexpr dart::compiler::target::word Code_entry_point_offset[] = { 8, 24, 16, 32}; static constexpr dart::compiler::target::word Thread_write_barrier_wrappers_thread_offset[] = { - 1384, 1392, 1400, 1408, -1, -1, 1416, 1424, - 1432, 1440, 1448, -1, 1456, 1464, -1, -1}; + 1312, 1320, 1328, 1336, -1, -1, 1344, 1352, + 1360, 1368, 1376, -1, 1384, 1392, -1, -1}; static constexpr dart::compiler::target::word ApiError_InstanceSize = 16; static constexpr dart::compiler::target::word Array_InstanceSize = 24; static constexpr dart::compiler::target::word Array_header_size = 24; static constexpr dart::compiler::target::word Bool_InstanceSize = 12; -static constexpr dart::compiler::target::word Bytecode_InstanceSize = 88; static constexpr dart::compiler::target::word Capability_InstanceSize = 16; static constexpr dart::compiler::target::word Class_InstanceSize = 208; static constexpr dart::compiler::target::word Closure_InstanceSize = 56; @@ -994,7 +982,7 @@ static constexpr dart::compiler::target::word FfiTrampolineData_InstanceSize = static constexpr dart::compiler::target::word Field_InstanceSize = 104; static constexpr dart::compiler::target::word Float32x4_InstanceSize = 24; static constexpr dart::compiler::target::word Float64x2_InstanceSize = 24; -static constexpr dart::compiler::target::word Function_InstanceSize = 152; +static constexpr dart::compiler::target::word Function_InstanceSize = 144; static constexpr dart::compiler::target::word FutureOr_InstanceSize = 16; static constexpr dart::compiler::target::word GrowableObjectArray_InstanceSize = 32; @@ -1007,7 +995,7 @@ static constexpr dart::compiler::target::word static constexpr dart::compiler::target::word Int32x4_InstanceSize = 24; static constexpr dart::compiler::target::word Integer_InstanceSize = 8; static constexpr dart::compiler::target::word KernelProgramInfo_InstanceSize = - 128; + 120; static constexpr dart::compiler::target::word LanguageError_InstanceSize = 48; static constexpr dart::compiler::target::word Library_InstanceSize = 160; static constexpr dart::compiler::target::word LibraryPrefix_InstanceSize = 40; @@ -1026,8 +1014,6 @@ static constexpr dart::compiler::target::word Number_InstanceSize = 8; static constexpr dart::compiler::target::word Object_InstanceSize = 8; static constexpr dart::compiler::target::word ObjectPool_InstanceSize = 16; static constexpr dart::compiler::target::word OneByteString_InstanceSize = 16; -static constexpr dart::compiler::target::word ParameterTypeCheck_InstanceSize = - 48; static constexpr dart::compiler::target::word PatchClass_InstanceSize = 48; static constexpr dart::compiler::target::word PcDescriptors_HeaderSize = 16; static constexpr dart::compiler::target::word Pointer_InstanceSize = 24; @@ -1067,7 +1053,7 @@ static constexpr dart::compiler::target::word #if defined(TARGET_ARCH_IA32) static constexpr dart::compiler::target::word Function_usage_counter_offset = - 76; + 84; static constexpr dart::compiler::target::word ICData_receivers_static_type_offset = 16; static constexpr dart::compiler::target::word ObjectPool_elements_start_offset = @@ -1181,9 +1167,9 @@ static constexpr dart::compiler::target::word Function_code_offset = 44; static constexpr dart::compiler::target::word Function_data_offset = 36; static constexpr dart::compiler::target::word Function_entry_point_offset[] = { 4, 8}; -static constexpr dart::compiler::target::word Function_kind_tag_offset = 64; +static constexpr dart::compiler::target::word Function_kind_tag_offset = 72; static constexpr dart::compiler::target::word Function_packed_fields_offset = - 68; + 76; static constexpr dart::compiler::target::word Function_parameter_names_offset = 28; static constexpr dart::compiler::target::word Function_parameter_types_offset = @@ -1265,159 +1251,155 @@ static constexpr dart::compiler::target::word String_hash_offset = 8; static constexpr dart::compiler::target::word String_length_offset = 4; static constexpr dart::compiler::target::word SubtypeTestCache_cache_offset = 4; static constexpr dart::compiler::target::word - Thread_AllocateArray_entry_point_offset = 384; + Thread_AllocateArray_entry_point_offset = 376; static constexpr dart::compiler::target::word Thread_active_exception_offset = - 700; + 664; static constexpr dart::compiler::target::word Thread_active_stacktrace_offset = - 704; + 668; static constexpr dart::compiler::target::word Thread_array_write_barrier_code_offset = 128; static constexpr dart::compiler::target::word - Thread_array_write_barrier_entry_point_offset = 276; + Thread_array_write_barrier_entry_point_offset = 272; static constexpr dart::compiler::target::word - Thread_allocate_mint_with_fpu_regs_entry_point_offset = 284; + Thread_allocate_mint_with_fpu_regs_entry_point_offset = 280; static constexpr dart::compiler::target::word - Thread_allocate_mint_with_fpu_regs_stub_offset = 192; + Thread_allocate_mint_with_fpu_regs_stub_offset = 188; static constexpr dart::compiler::target::word - Thread_allocate_mint_without_fpu_regs_entry_point_offset = 288; + Thread_allocate_mint_without_fpu_regs_entry_point_offset = 284; static constexpr dart::compiler::target::word - Thread_allocate_mint_without_fpu_regs_stub_offset = 196; + Thread_allocate_mint_without_fpu_regs_stub_offset = 192; static constexpr dart::compiler::target::word - Thread_allocate_object_entry_point_offset = 292; + Thread_allocate_object_entry_point_offset = 288; static constexpr dart::compiler::target::word - Thread_allocate_object_stub_offset = 200; + Thread_allocate_object_stub_offset = 196; static constexpr dart::compiler::target::word - Thread_allocate_object_parameterized_entry_point_offset = 296; + Thread_allocate_object_parameterized_entry_point_offset = 292; static constexpr dart::compiler::target::word - Thread_allocate_object_parameterized_stub_offset = 204; + Thread_allocate_object_parameterized_stub_offset = 200; static constexpr dart::compiler::target::word - Thread_allocate_object_slow_entry_point_offset = 300; + Thread_allocate_object_slow_entry_point_offset = 296; static constexpr dart::compiler::target::word - Thread_allocate_object_slow_stub_offset = 208; -static constexpr dart::compiler::target::word Thread_api_top_scope_offset = 736; + Thread_allocate_object_slow_stub_offset = 204; +static constexpr dart::compiler::target::word Thread_api_top_scope_offset = 700; static constexpr dart::compiler::target::word Thread_async_stack_trace_offset = 96; static constexpr dart::compiler::target::word - Thread_auto_scope_native_wrapper_entry_point_offset = 344; + Thread_auto_scope_native_wrapper_entry_point_offset = 340; static constexpr dart::compiler::target::word Thread_bool_false_offset = 120; static constexpr dart::compiler::target::word Thread_bool_true_offset = 116; static constexpr dart::compiler::target::word - Thread_bootstrap_native_wrapper_entry_point_offset = 336; + Thread_bootstrap_native_wrapper_entry_point_offset = 332; static constexpr dart::compiler::target::word - Thread_call_to_runtime_entry_point_offset = 280; + Thread_call_to_runtime_entry_point_offset = 276; static constexpr dart::compiler::target::word - Thread_call_to_runtime_stub_offset = 148; -static constexpr dart::compiler::target::word Thread_dart_stream_offset = 744; + Thread_call_to_runtime_stub_offset = 144; +static constexpr dart::compiler::target::word Thread_dart_stream_offset = 708; static constexpr dart::compiler::target::word Thread_dispatch_table_array_offset = 48; static constexpr dart::compiler::target::word Thread_optimize_entry_offset = - 320; -static constexpr dart::compiler::target::word Thread_optimize_stub_offset = 236; + 316; +static constexpr dart::compiler::target::word Thread_optimize_stub_offset = 232; static constexpr dart::compiler::target::word Thread_deoptimize_entry_offset = - 324; + 320; static constexpr dart::compiler::target::word Thread_deoptimize_stub_offset = - 240; + 236; static constexpr dart::compiler::target::word Thread_double_abs_address_offset = - 364; + 356; static constexpr dart::compiler::target::word - Thread_double_negate_address_offset = 360; + Thread_double_negate_address_offset = 352; static constexpr dart::compiler::target::word Thread_end_offset = 56; static constexpr dart::compiler::target::word - Thread_enter_safepoint_stub_offset = 260; + Thread_enter_safepoint_stub_offset = 256; static constexpr dart::compiler::target::word Thread_execution_state_offset = - 720; + 684; static constexpr dart::compiler::target::word - Thread_exit_safepoint_stub_offset = 264; + Thread_exit_safepoint_stub_offset = 260; static constexpr dart::compiler::target::word - Thread_call_native_through_safepoint_stub_offset = 268; + Thread_call_native_through_safepoint_stub_offset = 264; static constexpr dart::compiler::target::word - Thread_call_native_through_safepoint_entry_point_offset = 328; + Thread_call_native_through_safepoint_entry_point_offset = 324; static constexpr dart::compiler::target::word Thread_fix_allocation_stub_code_offset = 136; static constexpr dart::compiler::target::word Thread_fix_callers_target_code_offset = 132; static constexpr dart::compiler::target::word - Thread_float_absolute_address_offset = 376; + Thread_float_absolute_address_offset = 368; static constexpr dart::compiler::target::word - Thread_float_negate_address_offset = 372; + Thread_float_negate_address_offset = 364; static constexpr dart::compiler::target::word Thread_float_not_address_offset = - 368; + 360; static constexpr dart::compiler::target::word - Thread_float_zerow_address_offset = 380; + Thread_float_zerow_address_offset = 372; static constexpr dart::compiler::target::word Thread_global_object_pool_offset = - 708; -static constexpr dart::compiler::target::word - Thread_interpret_call_entry_point_offset = 348; -static constexpr dart::compiler::target::word - Thread_invoke_dart_code_from_bytecode_stub_offset = 144; + 672; static constexpr dart::compiler::target::word Thread_invoke_dart_code_stub_offset = 140; static constexpr dart::compiler::target::word Thread_exit_through_ffi_offset = - 732; + 696; static constexpr dart::compiler::target::word Thread_isolate_offset = 44; static constexpr dart::compiler::target::word Thread_field_table_values_offset = 68; static constexpr dart::compiler::target::word - Thread_lazy_deopt_from_return_stub_offset = 244; + Thread_lazy_deopt_from_return_stub_offset = 240; static constexpr dart::compiler::target::word - Thread_lazy_deopt_from_throw_stub_offset = 248; + Thread_lazy_deopt_from_throw_stub_offset = 244; static constexpr dart::compiler::target::word - Thread_lazy_specialize_type_test_stub_offset = 256; + Thread_lazy_specialize_type_test_stub_offset = 252; static constexpr dart::compiler::target::word Thread_marking_stack_block_offset = 84; static constexpr dart::compiler::target::word - Thread_megamorphic_call_checked_entry_offset = 312; + Thread_megamorphic_call_checked_entry_offset = 308; static constexpr dart::compiler::target::word - Thread_switchable_call_miss_entry_offset = 316; + Thread_switchable_call_miss_entry_offset = 312; static constexpr dart::compiler::target::word - Thread_switchable_call_miss_stub_offset = 220; + Thread_switchable_call_miss_stub_offset = 216; static constexpr dart::compiler::target::word - Thread_no_scope_native_wrapper_entry_point_offset = 340; + Thread_no_scope_native_wrapper_entry_point_offset = 336; static constexpr dart::compiler::target::word - Thread_late_initialization_error_shared_with_fpu_regs_stub_offset = 156; + Thread_late_initialization_error_shared_with_fpu_regs_stub_offset = 152; static constexpr dart::compiler::target::word - Thread_late_initialization_error_shared_without_fpu_regs_stub_offset = 152; + Thread_late_initialization_error_shared_without_fpu_regs_stub_offset = 148; static constexpr dart::compiler::target::word - Thread_null_error_shared_with_fpu_regs_stub_offset = 164; + Thread_null_error_shared_with_fpu_regs_stub_offset = 160; static constexpr dart::compiler::target::word - Thread_null_error_shared_without_fpu_regs_stub_offset = 160; + Thread_null_error_shared_without_fpu_regs_stub_offset = 156; static constexpr dart::compiler::target::word - Thread_null_arg_error_shared_with_fpu_regs_stub_offset = 172; + Thread_null_arg_error_shared_with_fpu_regs_stub_offset = 168; static constexpr dart::compiler::target::word - Thread_null_arg_error_shared_without_fpu_regs_stub_offset = 168; + Thread_null_arg_error_shared_without_fpu_regs_stub_offset = 164; static constexpr dart::compiler::target::word - Thread_null_cast_error_shared_with_fpu_regs_stub_offset = 180; + Thread_null_cast_error_shared_with_fpu_regs_stub_offset = 176; static constexpr dart::compiler::target::word - Thread_null_cast_error_shared_without_fpu_regs_stub_offset = 176; + Thread_null_cast_error_shared_without_fpu_regs_stub_offset = 172; static constexpr dart::compiler::target::word - Thread_range_error_shared_with_fpu_regs_stub_offset = 188; + Thread_range_error_shared_with_fpu_regs_stub_offset = 184; static constexpr dart::compiler::target::word - Thread_range_error_shared_without_fpu_regs_stub_offset = 184; + Thread_range_error_shared_without_fpu_regs_stub_offset = 180; static constexpr dart::compiler::target::word Thread_object_null_offset = 112; static constexpr dart::compiler::target::word - Thread_predefined_symbols_address_offset = 352; -static constexpr dart::compiler::target::word Thread_resume_pc_offset = 712; + Thread_predefined_symbols_address_offset = 344; +static constexpr dart::compiler::target::word Thread_resume_pc_offset = 676; static constexpr dart::compiler::target::word - Thread_saved_shadow_call_stack_offset = 716; + Thread_saved_shadow_call_stack_offset = 680; static constexpr dart::compiler::target::word Thread_safepoint_state_offset = - 724; + 688; static constexpr dart::compiler::target::word - Thread_slow_type_test_stub_offset = 252; + Thread_slow_type_test_stub_offset = 248; static constexpr dart::compiler::target::word - Thread_slow_type_test_entry_point_offset = 332; + Thread_slow_type_test_entry_point_offset = 328; static constexpr dart::compiler::target::word Thread_stack_limit_offset = 36; static constexpr dart::compiler::target::word Thread_saved_stack_limit_offset = 60; static constexpr dart::compiler::target::word Thread_stack_overflow_flags_offset = 64; static constexpr dart::compiler::target::word - Thread_stack_overflow_shared_with_fpu_regs_entry_point_offset = 308; + Thread_stack_overflow_shared_with_fpu_regs_entry_point_offset = 304; static constexpr dart::compiler::target::word - Thread_stack_overflow_shared_with_fpu_regs_stub_offset = 216; + Thread_stack_overflow_shared_with_fpu_regs_stub_offset = 212; static constexpr dart::compiler::target::word - Thread_stack_overflow_shared_without_fpu_regs_entry_point_offset = 304; + Thread_stack_overflow_shared_without_fpu_regs_entry_point_offset = 300; static constexpr dart::compiler::target::word - Thread_stack_overflow_shared_without_fpu_regs_stub_offset = 212; + Thread_stack_overflow_shared_without_fpu_regs_stub_offset = 208; static constexpr dart::compiler::target::word Thread_store_buffer_block_offset = 80; static constexpr dart::compiler::target::word @@ -1430,10 +1412,10 @@ static constexpr dart::compiler::target::word Thread_vm_tag_offset = 92; static constexpr dart::compiler::target::word Thread_write_barrier_code_offset = 124; static constexpr dart::compiler::target::word - Thread_write_barrier_entry_point_offset = 272; + Thread_write_barrier_entry_point_offset = 268; static constexpr dart::compiler::target::word Thread_write_barrier_mask_offset = 40; -static constexpr dart::compiler::target::word Thread_callback_code_offset = 728; +static constexpr dart::compiler::target::word Thread_callback_code_offset = 692; static constexpr dart::compiler::target::word TimelineStream_enabled_offset = 8; static constexpr dart::compiler::target::word TwoByteString_data_offset = 12; static constexpr dart::compiler::target::word Type_arguments_offset = 16; @@ -1485,7 +1467,6 @@ static constexpr dart::compiler::target::word ApiError_InstanceSize = 8; static constexpr dart::compiler::target::word Array_InstanceSize = 12; static constexpr dart::compiler::target::word Array_header_size = 12; static constexpr dart::compiler::target::word Bool_InstanceSize = 8; -static constexpr dart::compiler::target::word Bytecode_InstanceSize = 48; static constexpr dart::compiler::target::word Capability_InstanceSize = 16; static constexpr dart::compiler::target::word Class_InstanceSize = 128; static constexpr dart::compiler::target::word Closure_InstanceSize = 28; @@ -1525,7 +1506,7 @@ static constexpr dart::compiler::target::word static constexpr dart::compiler::target::word Int32x4_InstanceSize = 24; static constexpr dart::compiler::target::word Integer_InstanceSize = 4; static constexpr dart::compiler::target::word KernelProgramInfo_InstanceSize = - 64; + 60; static constexpr dart::compiler::target::word LanguageError_InstanceSize = 28; static constexpr dart::compiler::target::word Library_InstanceSize = 84; static constexpr dart::compiler::target::word LibraryPrefix_InstanceSize = 20; @@ -1544,8 +1525,6 @@ static constexpr dart::compiler::target::word Number_InstanceSize = 4; static constexpr dart::compiler::target::word Object_InstanceSize = 4; static constexpr dart::compiler::target::word ObjectPool_InstanceSize = 8; static constexpr dart::compiler::target::word OneByteString_InstanceSize = 12; -static constexpr dart::compiler::target::word ParameterTypeCheck_InstanceSize = - 24; static constexpr dart::compiler::target::word PatchClass_InstanceSize = 24; static constexpr dart::compiler::target::word PcDescriptors_HeaderSize = 8; static constexpr dart::compiler::target::word Pointer_InstanceSize = 12; @@ -1785,160 +1764,156 @@ static constexpr dart::compiler::target::word String_hash_offset = 4; static constexpr dart::compiler::target::word String_length_offset = 8; static constexpr dart::compiler::target::word SubtypeTestCache_cache_offset = 8; static constexpr dart::compiler::target::word - Thread_AllocateArray_entry_point_offset = 752; + Thread_AllocateArray_entry_point_offset = 736; static constexpr dart::compiler::target::word Thread_active_exception_offset = - 1544; + 1472; static constexpr dart::compiler::target::word Thread_active_stacktrace_offset = - 1552; + 1480; static constexpr dart::compiler::target::word Thread_array_write_barrier_code_offset = 240; static constexpr dart::compiler::target::word - Thread_array_write_barrier_entry_point_offset = 536; + Thread_array_write_barrier_entry_point_offset = 528; static constexpr dart::compiler::target::word - Thread_allocate_mint_with_fpu_regs_entry_point_offset = 552; + Thread_allocate_mint_with_fpu_regs_entry_point_offset = 544; static constexpr dart::compiler::target::word - Thread_allocate_mint_with_fpu_regs_stub_offset = 368; + Thread_allocate_mint_with_fpu_regs_stub_offset = 360; static constexpr dart::compiler::target::word - Thread_allocate_mint_without_fpu_regs_entry_point_offset = 560; + Thread_allocate_mint_without_fpu_regs_entry_point_offset = 552; static constexpr dart::compiler::target::word - Thread_allocate_mint_without_fpu_regs_stub_offset = 376; + Thread_allocate_mint_without_fpu_regs_stub_offset = 368; static constexpr dart::compiler::target::word - Thread_allocate_object_entry_point_offset = 568; + Thread_allocate_object_entry_point_offset = 560; static constexpr dart::compiler::target::word - Thread_allocate_object_stub_offset = 384; + Thread_allocate_object_stub_offset = 376; static constexpr dart::compiler::target::word - Thread_allocate_object_parameterized_entry_point_offset = 576; + Thread_allocate_object_parameterized_entry_point_offset = 568; static constexpr dart::compiler::target::word - Thread_allocate_object_parameterized_stub_offset = 392; + Thread_allocate_object_parameterized_stub_offset = 384; static constexpr dart::compiler::target::word - Thread_allocate_object_slow_entry_point_offset = 584; + Thread_allocate_object_slow_entry_point_offset = 576; static constexpr dart::compiler::target::word - Thread_allocate_object_slow_stub_offset = 400; + Thread_allocate_object_slow_stub_offset = 392; static constexpr dart::compiler::target::word Thread_api_top_scope_offset = - 1616; + 1544; static constexpr dart::compiler::target::word Thread_async_stack_trace_offset = 192; static constexpr dart::compiler::target::word - Thread_auto_scope_native_wrapper_entry_point_offset = 672; + Thread_auto_scope_native_wrapper_entry_point_offset = 664; static constexpr dart::compiler::target::word Thread_bool_false_offset = 224; static constexpr dart::compiler::target::word Thread_bool_true_offset = 216; static constexpr dart::compiler::target::word - Thread_bootstrap_native_wrapper_entry_point_offset = 656; + Thread_bootstrap_native_wrapper_entry_point_offset = 648; static constexpr dart::compiler::target::word - Thread_call_to_runtime_entry_point_offset = 544; + Thread_call_to_runtime_entry_point_offset = 536; static constexpr dart::compiler::target::word - Thread_call_to_runtime_stub_offset = 280; -static constexpr dart::compiler::target::word Thread_dart_stream_offset = 1632; + Thread_call_to_runtime_stub_offset = 272; +static constexpr dart::compiler::target::word Thread_dart_stream_offset = 1560; static constexpr dart::compiler::target::word Thread_dispatch_table_array_offset = 96; static constexpr dart::compiler::target::word Thread_optimize_entry_offset = - 624; -static constexpr dart::compiler::target::word Thread_optimize_stub_offset = 456; + 616; +static constexpr dart::compiler::target::word Thread_optimize_stub_offset = 448; static constexpr dart::compiler::target::word Thread_deoptimize_entry_offset = - 632; + 624; static constexpr dart::compiler::target::word Thread_deoptimize_stub_offset = - 464; + 456; static constexpr dart::compiler::target::word Thread_double_abs_address_offset = - 712; + 696; static constexpr dart::compiler::target::word - Thread_double_negate_address_offset = 704; + Thread_double_negate_address_offset = 688; static constexpr dart::compiler::target::word Thread_end_offset = 112; static constexpr dart::compiler::target::word - Thread_enter_safepoint_stub_offset = 504; + Thread_enter_safepoint_stub_offset = 496; static constexpr dart::compiler::target::word Thread_execution_state_offset = - 1584; + 1512; static constexpr dart::compiler::target::word - Thread_exit_safepoint_stub_offset = 512; + Thread_exit_safepoint_stub_offset = 504; static constexpr dart::compiler::target::word - Thread_call_native_through_safepoint_stub_offset = 520; + Thread_call_native_through_safepoint_stub_offset = 512; static constexpr dart::compiler::target::word - Thread_call_native_through_safepoint_entry_point_offset = 640; + Thread_call_native_through_safepoint_entry_point_offset = 632; static constexpr dart::compiler::target::word Thread_fix_allocation_stub_code_offset = 256; static constexpr dart::compiler::target::word Thread_fix_callers_target_code_offset = 248; static constexpr dart::compiler::target::word - Thread_float_absolute_address_offset = 736; + Thread_float_absolute_address_offset = 720; static constexpr dart::compiler::target::word - Thread_float_negate_address_offset = 728; + Thread_float_negate_address_offset = 712; static constexpr dart::compiler::target::word Thread_float_not_address_offset = - 720; + 704; static constexpr dart::compiler::target::word - Thread_float_zerow_address_offset = 744; + Thread_float_zerow_address_offset = 728; static constexpr dart::compiler::target::word Thread_global_object_pool_offset = - 1560; -static constexpr dart::compiler::target::word - Thread_interpret_call_entry_point_offset = 680; -static constexpr dart::compiler::target::word - Thread_invoke_dart_code_from_bytecode_stub_offset = 272; + 1488; static constexpr dart::compiler::target::word Thread_invoke_dart_code_stub_offset = 264; static constexpr dart::compiler::target::word Thread_exit_through_ffi_offset = - 1608; + 1536; static constexpr dart::compiler::target::word Thread_isolate_offset = 88; static constexpr dart::compiler::target::word Thread_field_table_values_offset = 136; static constexpr dart::compiler::target::word - Thread_lazy_deopt_from_return_stub_offset = 472; + Thread_lazy_deopt_from_return_stub_offset = 464; static constexpr dart::compiler::target::word - Thread_lazy_deopt_from_throw_stub_offset = 480; + Thread_lazy_deopt_from_throw_stub_offset = 472; static constexpr dart::compiler::target::word - Thread_lazy_specialize_type_test_stub_offset = 496; + Thread_lazy_specialize_type_test_stub_offset = 488; static constexpr dart::compiler::target::word Thread_marking_stack_block_offset = 168; static constexpr dart::compiler::target::word - Thread_megamorphic_call_checked_entry_offset = 608; + Thread_megamorphic_call_checked_entry_offset = 600; static constexpr dart::compiler::target::word - Thread_switchable_call_miss_entry_offset = 616; + Thread_switchable_call_miss_entry_offset = 608; static constexpr dart::compiler::target::word - Thread_switchable_call_miss_stub_offset = 424; + Thread_switchable_call_miss_stub_offset = 416; static constexpr dart::compiler::target::word - Thread_no_scope_native_wrapper_entry_point_offset = 664; + Thread_no_scope_native_wrapper_entry_point_offset = 656; static constexpr dart::compiler::target::word - Thread_late_initialization_error_shared_with_fpu_regs_stub_offset = 296; + Thread_late_initialization_error_shared_with_fpu_regs_stub_offset = 288; static constexpr dart::compiler::target::word - Thread_late_initialization_error_shared_without_fpu_regs_stub_offset = 288; + Thread_late_initialization_error_shared_without_fpu_regs_stub_offset = 280; static constexpr dart::compiler::target::word - Thread_null_error_shared_with_fpu_regs_stub_offset = 312; + Thread_null_error_shared_with_fpu_regs_stub_offset = 304; static constexpr dart::compiler::target::word - Thread_null_error_shared_without_fpu_regs_stub_offset = 304; + Thread_null_error_shared_without_fpu_regs_stub_offset = 296; static constexpr dart::compiler::target::word - Thread_null_arg_error_shared_with_fpu_regs_stub_offset = 328; + Thread_null_arg_error_shared_with_fpu_regs_stub_offset = 320; static constexpr dart::compiler::target::word - Thread_null_arg_error_shared_without_fpu_regs_stub_offset = 320; + Thread_null_arg_error_shared_without_fpu_regs_stub_offset = 312; static constexpr dart::compiler::target::word - Thread_null_cast_error_shared_with_fpu_regs_stub_offset = 344; + Thread_null_cast_error_shared_with_fpu_regs_stub_offset = 336; static constexpr dart::compiler::target::word - Thread_null_cast_error_shared_without_fpu_regs_stub_offset = 336; + Thread_null_cast_error_shared_without_fpu_regs_stub_offset = 328; static constexpr dart::compiler::target::word - Thread_range_error_shared_with_fpu_regs_stub_offset = 360; + Thread_range_error_shared_with_fpu_regs_stub_offset = 352; static constexpr dart::compiler::target::word - Thread_range_error_shared_without_fpu_regs_stub_offset = 352; + Thread_range_error_shared_without_fpu_regs_stub_offset = 344; static constexpr dart::compiler::target::word Thread_object_null_offset = 208; static constexpr dart::compiler::target::word - Thread_predefined_symbols_address_offset = 688; -static constexpr dart::compiler::target::word Thread_resume_pc_offset = 1568; + Thread_predefined_symbols_address_offset = 672; +static constexpr dart::compiler::target::word Thread_resume_pc_offset = 1496; static constexpr dart::compiler::target::word - Thread_saved_shadow_call_stack_offset = 1576; + Thread_saved_shadow_call_stack_offset = 1504; static constexpr dart::compiler::target::word Thread_safepoint_state_offset = - 1592; + 1520; static constexpr dart::compiler::target::word - Thread_slow_type_test_stub_offset = 488; + Thread_slow_type_test_stub_offset = 480; static constexpr dart::compiler::target::word - Thread_slow_type_test_entry_point_offset = 648; + Thread_slow_type_test_entry_point_offset = 640; static constexpr dart::compiler::target::word Thread_stack_limit_offset = 72; static constexpr dart::compiler::target::word Thread_saved_stack_limit_offset = 120; static constexpr dart::compiler::target::word Thread_stack_overflow_flags_offset = 128; static constexpr dart::compiler::target::word - Thread_stack_overflow_shared_with_fpu_regs_entry_point_offset = 600; + Thread_stack_overflow_shared_with_fpu_regs_entry_point_offset = 592; static constexpr dart::compiler::target::word - Thread_stack_overflow_shared_with_fpu_regs_stub_offset = 416; + Thread_stack_overflow_shared_with_fpu_regs_stub_offset = 408; static constexpr dart::compiler::target::word - Thread_stack_overflow_shared_without_fpu_regs_entry_point_offset = 592; + Thread_stack_overflow_shared_without_fpu_regs_entry_point_offset = 584; static constexpr dart::compiler::target::word - Thread_stack_overflow_shared_without_fpu_regs_stub_offset = 408; + Thread_stack_overflow_shared_without_fpu_regs_stub_offset = 400; static constexpr dart::compiler::target::word Thread_store_buffer_block_offset = 160; static constexpr dart::compiler::target::word @@ -1951,11 +1926,11 @@ static constexpr dart::compiler::target::word Thread_vm_tag_offset = 184; static constexpr dart::compiler::target::word Thread_write_barrier_code_offset = 232; static constexpr dart::compiler::target::word - Thread_write_barrier_entry_point_offset = 528; + Thread_write_barrier_entry_point_offset = 520; static constexpr dart::compiler::target::word Thread_write_barrier_mask_offset = 80; static constexpr dart::compiler::target::word Thread_callback_code_offset = - 1600; + 1528; static constexpr dart::compiler::target::word TimelineStream_enabled_offset = 16; static constexpr dart::compiler::target::word TwoByteString_data_offset = 16; @@ -2006,14 +1981,13 @@ static constexpr dart::compiler::target::word Code_entry_point_offset[] = { 8, 24, 16, 32}; static constexpr dart::compiler::target::word Thread_write_barrier_wrappers_thread_offset[] = { - 1384, 1392, 1400, 1408, 1416, 1424, 1432, 1440, 1448, 1456, 1464, - 1472, 1480, 1488, 1496, -1, -1, -1, -1, 1504, 1512, -1, - -1, 1520, 1528, 1536, -1, -1, -1, -1, -1, -1}; + 1312, 1320, 1328, 1336, 1344, 1352, 1360, 1368, 1376, 1384, 1392, + 1400, 1408, 1416, 1424, -1, -1, -1, -1, 1432, 1440, -1, + -1, 1448, 1456, 1464, -1, -1, -1, -1, -1, -1}; static constexpr dart::compiler::target::word ApiError_InstanceSize = 16; static constexpr dart::compiler::target::word Array_InstanceSize = 24; static constexpr dart::compiler::target::word Array_header_size = 24; static constexpr dart::compiler::target::word Bool_InstanceSize = 12; -static constexpr dart::compiler::target::word Bytecode_InstanceSize = 88; static constexpr dart::compiler::target::word Capability_InstanceSize = 16; static constexpr dart::compiler::target::word Class_InstanceSize = 208; static constexpr dart::compiler::target::word Closure_InstanceSize = 56; @@ -2040,7 +2014,7 @@ static constexpr dart::compiler::target::word FfiTrampolineData_InstanceSize = static constexpr dart::compiler::target::word Field_InstanceSize = 104; static constexpr dart::compiler::target::word Float32x4_InstanceSize = 24; static constexpr dart::compiler::target::word Float64x2_InstanceSize = 24; -static constexpr dart::compiler::target::word Function_InstanceSize = 152; +static constexpr dart::compiler::target::word Function_InstanceSize = 144; static constexpr dart::compiler::target::word FutureOr_InstanceSize = 16; static constexpr dart::compiler::target::word GrowableObjectArray_InstanceSize = 32; @@ -2053,7 +2027,7 @@ static constexpr dart::compiler::target::word static constexpr dart::compiler::target::word Int32x4_InstanceSize = 24; static constexpr dart::compiler::target::word Integer_InstanceSize = 8; static constexpr dart::compiler::target::word KernelProgramInfo_InstanceSize = - 128; + 120; static constexpr dart::compiler::target::word LanguageError_InstanceSize = 48; static constexpr dart::compiler::target::word Library_InstanceSize = 160; static constexpr dart::compiler::target::word LibraryPrefix_InstanceSize = 40; @@ -2072,8 +2046,6 @@ static constexpr dart::compiler::target::word Number_InstanceSize = 8; static constexpr dart::compiler::target::word Object_InstanceSize = 8; static constexpr dart::compiler::target::word ObjectPool_InstanceSize = 16; static constexpr dart::compiler::target::word OneByteString_InstanceSize = 16; -static constexpr dart::compiler::target::word ParameterTypeCheck_InstanceSize = - 48; static constexpr dart::compiler::target::word PatchClass_InstanceSize = 48; static constexpr dart::compiler::target::word PcDescriptors_HeaderSize = 16; static constexpr dart::compiler::target::word Pointer_InstanceSize = 24; @@ -2115,7 +2087,7 @@ static constexpr dart::compiler::target::word #if defined(TARGET_ARCH_ARM) static constexpr dart::compiler::target::word Function_usage_counter_offset = - 76; + 84; static constexpr dart::compiler::target::word ICData_receivers_static_type_offset = 16; static constexpr dart::compiler::target::word ObjectPool_elements_start_offset = @@ -2227,9 +2199,9 @@ static constexpr dart::compiler::target::word Function_code_offset = 44; static constexpr dart::compiler::target::word Function_data_offset = 36; static constexpr dart::compiler::target::word Function_entry_point_offset[] = { 4, 8}; -static constexpr dart::compiler::target::word Function_kind_tag_offset = 64; +static constexpr dart::compiler::target::word Function_kind_tag_offset = 72; static constexpr dart::compiler::target::word Function_packed_fields_offset = - 68; + 76; static constexpr dart::compiler::target::word Function_parameter_names_offset = 28; static constexpr dart::compiler::target::word Function_parameter_types_offset = @@ -2310,159 +2282,155 @@ static constexpr dart::compiler::target::word String_hash_offset = 8; static constexpr dart::compiler::target::word String_length_offset = 4; static constexpr dart::compiler::target::word SubtypeTestCache_cache_offset = 4; static constexpr dart::compiler::target::word - Thread_AllocateArray_entry_point_offset = 384; + Thread_AllocateArray_entry_point_offset = 376; static constexpr dart::compiler::target::word Thread_active_exception_offset = - 732; + 696; static constexpr dart::compiler::target::word Thread_active_stacktrace_offset = - 736; + 700; static constexpr dart::compiler::target::word Thread_array_write_barrier_code_offset = 128; static constexpr dart::compiler::target::word - Thread_array_write_barrier_entry_point_offset = 276; + Thread_array_write_barrier_entry_point_offset = 272; static constexpr dart::compiler::target::word - Thread_allocate_mint_with_fpu_regs_entry_point_offset = 284; + Thread_allocate_mint_with_fpu_regs_entry_point_offset = 280; static constexpr dart::compiler::target::word - Thread_allocate_mint_with_fpu_regs_stub_offset = 192; + Thread_allocate_mint_with_fpu_regs_stub_offset = 188; static constexpr dart::compiler::target::word - Thread_allocate_mint_without_fpu_regs_entry_point_offset = 288; + Thread_allocate_mint_without_fpu_regs_entry_point_offset = 284; static constexpr dart::compiler::target::word - Thread_allocate_mint_without_fpu_regs_stub_offset = 196; + Thread_allocate_mint_without_fpu_regs_stub_offset = 192; static constexpr dart::compiler::target::word - Thread_allocate_object_entry_point_offset = 292; + Thread_allocate_object_entry_point_offset = 288; static constexpr dart::compiler::target::word - Thread_allocate_object_stub_offset = 200; + Thread_allocate_object_stub_offset = 196; static constexpr dart::compiler::target::word - Thread_allocate_object_parameterized_entry_point_offset = 296; + Thread_allocate_object_parameterized_entry_point_offset = 292; static constexpr dart::compiler::target::word - Thread_allocate_object_parameterized_stub_offset = 204; + Thread_allocate_object_parameterized_stub_offset = 200; static constexpr dart::compiler::target::word - Thread_allocate_object_slow_entry_point_offset = 300; + Thread_allocate_object_slow_entry_point_offset = 296; static constexpr dart::compiler::target::word - Thread_allocate_object_slow_stub_offset = 208; -static constexpr dart::compiler::target::word Thread_api_top_scope_offset = 768; + Thread_allocate_object_slow_stub_offset = 204; +static constexpr dart::compiler::target::word Thread_api_top_scope_offset = 732; static constexpr dart::compiler::target::word Thread_async_stack_trace_offset = 96; static constexpr dart::compiler::target::word - Thread_auto_scope_native_wrapper_entry_point_offset = 344; + Thread_auto_scope_native_wrapper_entry_point_offset = 340; static constexpr dart::compiler::target::word Thread_bool_false_offset = 120; static constexpr dart::compiler::target::word Thread_bool_true_offset = 116; static constexpr dart::compiler::target::word - Thread_bootstrap_native_wrapper_entry_point_offset = 336; + Thread_bootstrap_native_wrapper_entry_point_offset = 332; static constexpr dart::compiler::target::word - Thread_call_to_runtime_entry_point_offset = 280; + Thread_call_to_runtime_entry_point_offset = 276; static constexpr dart::compiler::target::word - Thread_call_to_runtime_stub_offset = 148; -static constexpr dart::compiler::target::word Thread_dart_stream_offset = 776; + Thread_call_to_runtime_stub_offset = 144; +static constexpr dart::compiler::target::word Thread_dart_stream_offset = 740; static constexpr dart::compiler::target::word Thread_dispatch_table_array_offset = 48; static constexpr dart::compiler::target::word Thread_optimize_entry_offset = - 320; -static constexpr dart::compiler::target::word Thread_optimize_stub_offset = 236; + 316; +static constexpr dart::compiler::target::word Thread_optimize_stub_offset = 232; static constexpr dart::compiler::target::word Thread_deoptimize_entry_offset = - 324; + 320; static constexpr dart::compiler::target::word Thread_deoptimize_stub_offset = - 240; + 236; static constexpr dart::compiler::target::word Thread_double_abs_address_offset = - 364; + 356; static constexpr dart::compiler::target::word - Thread_double_negate_address_offset = 360; + Thread_double_negate_address_offset = 352; static constexpr dart::compiler::target::word Thread_end_offset = 56; static constexpr dart::compiler::target::word - Thread_enter_safepoint_stub_offset = 260; + Thread_enter_safepoint_stub_offset = 256; static constexpr dart::compiler::target::word Thread_execution_state_offset = - 752; + 716; static constexpr dart::compiler::target::word - Thread_exit_safepoint_stub_offset = 264; + Thread_exit_safepoint_stub_offset = 260; static constexpr dart::compiler::target::word - Thread_call_native_through_safepoint_stub_offset = 268; + Thread_call_native_through_safepoint_stub_offset = 264; static constexpr dart::compiler::target::word - Thread_call_native_through_safepoint_entry_point_offset = 328; + Thread_call_native_through_safepoint_entry_point_offset = 324; static constexpr dart::compiler::target::word Thread_fix_allocation_stub_code_offset = 136; static constexpr dart::compiler::target::word Thread_fix_callers_target_code_offset = 132; static constexpr dart::compiler::target::word - Thread_float_absolute_address_offset = 376; + Thread_float_absolute_address_offset = 368; static constexpr dart::compiler::target::word - Thread_float_negate_address_offset = 372; + Thread_float_negate_address_offset = 364; static constexpr dart::compiler::target::word Thread_float_not_address_offset = - 368; + 360; static constexpr dart::compiler::target::word - Thread_float_zerow_address_offset = 380; + Thread_float_zerow_address_offset = 372; static constexpr dart::compiler::target::word Thread_global_object_pool_offset = - 740; -static constexpr dart::compiler::target::word - Thread_interpret_call_entry_point_offset = 348; -static constexpr dart::compiler::target::word - Thread_invoke_dart_code_from_bytecode_stub_offset = 144; + 704; static constexpr dart::compiler::target::word Thread_invoke_dart_code_stub_offset = 140; static constexpr dart::compiler::target::word Thread_exit_through_ffi_offset = - 764; + 728; static constexpr dart::compiler::target::word Thread_isolate_offset = 44; static constexpr dart::compiler::target::word Thread_field_table_values_offset = 68; static constexpr dart::compiler::target::word - Thread_lazy_deopt_from_return_stub_offset = 244; + Thread_lazy_deopt_from_return_stub_offset = 240; static constexpr dart::compiler::target::word - Thread_lazy_deopt_from_throw_stub_offset = 248; + Thread_lazy_deopt_from_throw_stub_offset = 244; static constexpr dart::compiler::target::word - Thread_lazy_specialize_type_test_stub_offset = 256; + Thread_lazy_specialize_type_test_stub_offset = 252; static constexpr dart::compiler::target::word Thread_marking_stack_block_offset = 84; static constexpr dart::compiler::target::word - Thread_megamorphic_call_checked_entry_offset = 312; + Thread_megamorphic_call_checked_entry_offset = 308; static constexpr dart::compiler::target::word - Thread_switchable_call_miss_entry_offset = 316; + Thread_switchable_call_miss_entry_offset = 312; static constexpr dart::compiler::target::word - Thread_switchable_call_miss_stub_offset = 220; + Thread_switchable_call_miss_stub_offset = 216; static constexpr dart::compiler::target::word - Thread_no_scope_native_wrapper_entry_point_offset = 340; + Thread_no_scope_native_wrapper_entry_point_offset = 336; static constexpr dart::compiler::target::word - Thread_late_initialization_error_shared_with_fpu_regs_stub_offset = 156; + Thread_late_initialization_error_shared_with_fpu_regs_stub_offset = 152; static constexpr dart::compiler::target::word - Thread_late_initialization_error_shared_without_fpu_regs_stub_offset = 152; + Thread_late_initialization_error_shared_without_fpu_regs_stub_offset = 148; static constexpr dart::compiler::target::word - Thread_null_error_shared_with_fpu_regs_stub_offset = 164; + Thread_null_error_shared_with_fpu_regs_stub_offset = 160; static constexpr dart::compiler::target::word - Thread_null_error_shared_without_fpu_regs_stub_offset = 160; + Thread_null_error_shared_without_fpu_regs_stub_offset = 156; static constexpr dart::compiler::target::word - Thread_null_arg_error_shared_with_fpu_regs_stub_offset = 172; + Thread_null_arg_error_shared_with_fpu_regs_stub_offset = 168; static constexpr dart::compiler::target::word - Thread_null_arg_error_shared_without_fpu_regs_stub_offset = 168; + Thread_null_arg_error_shared_without_fpu_regs_stub_offset = 164; static constexpr dart::compiler::target::word - Thread_null_cast_error_shared_with_fpu_regs_stub_offset = 180; + Thread_null_cast_error_shared_with_fpu_regs_stub_offset = 176; static constexpr dart::compiler::target::word - Thread_null_cast_error_shared_without_fpu_regs_stub_offset = 176; + Thread_null_cast_error_shared_without_fpu_regs_stub_offset = 172; static constexpr dart::compiler::target::word - Thread_range_error_shared_with_fpu_regs_stub_offset = 188; + Thread_range_error_shared_with_fpu_regs_stub_offset = 184; static constexpr dart::compiler::target::word - Thread_range_error_shared_without_fpu_regs_stub_offset = 184; + Thread_range_error_shared_without_fpu_regs_stub_offset = 180; static constexpr dart::compiler::target::word Thread_object_null_offset = 112; static constexpr dart::compiler::target::word - Thread_predefined_symbols_address_offset = 352; -static constexpr dart::compiler::target::word Thread_resume_pc_offset = 744; + Thread_predefined_symbols_address_offset = 344; +static constexpr dart::compiler::target::word Thread_resume_pc_offset = 708; static constexpr dart::compiler::target::word - Thread_saved_shadow_call_stack_offset = 748; + Thread_saved_shadow_call_stack_offset = 712; static constexpr dart::compiler::target::word Thread_safepoint_state_offset = - 756; + 720; static constexpr dart::compiler::target::word - Thread_slow_type_test_stub_offset = 252; + Thread_slow_type_test_stub_offset = 248; static constexpr dart::compiler::target::word - Thread_slow_type_test_entry_point_offset = 332; + Thread_slow_type_test_entry_point_offset = 328; static constexpr dart::compiler::target::word Thread_stack_limit_offset = 36; static constexpr dart::compiler::target::word Thread_saved_stack_limit_offset = 60; static constexpr dart::compiler::target::word Thread_stack_overflow_flags_offset = 64; static constexpr dart::compiler::target::word - Thread_stack_overflow_shared_with_fpu_regs_entry_point_offset = 308; + Thread_stack_overflow_shared_with_fpu_regs_entry_point_offset = 304; static constexpr dart::compiler::target::word - Thread_stack_overflow_shared_with_fpu_regs_stub_offset = 216; + Thread_stack_overflow_shared_with_fpu_regs_stub_offset = 212; static constexpr dart::compiler::target::word - Thread_stack_overflow_shared_without_fpu_regs_entry_point_offset = 304; + Thread_stack_overflow_shared_without_fpu_regs_entry_point_offset = 300; static constexpr dart::compiler::target::word - Thread_stack_overflow_shared_without_fpu_regs_stub_offset = 212; + Thread_stack_overflow_shared_without_fpu_regs_stub_offset = 208; static constexpr dart::compiler::target::word Thread_store_buffer_block_offset = 80; static constexpr dart::compiler::target::word @@ -2475,10 +2443,10 @@ static constexpr dart::compiler::target::word Thread_vm_tag_offset = 92; static constexpr dart::compiler::target::word Thread_write_barrier_code_offset = 124; static constexpr dart::compiler::target::word - Thread_write_barrier_entry_point_offset = 272; + Thread_write_barrier_entry_point_offset = 268; static constexpr dart::compiler::target::word Thread_write_barrier_mask_offset = 40; -static constexpr dart::compiler::target::word Thread_callback_code_offset = 760; +static constexpr dart::compiler::target::word Thread_callback_code_offset = 724; static constexpr dart::compiler::target::word TimelineStream_enabled_offset = 8; static constexpr dart::compiler::target::word TwoByteString_data_offset = 12; static constexpr dart::compiler::target::word Type_arguments_offset = 16; @@ -2525,12 +2493,11 @@ static constexpr dart::compiler::target::word Code_entry_point_offset[] = { 4, 12, 8, 16}; static constexpr dart::compiler::target::word Thread_write_barrier_wrappers_thread_offset[] = { - 700, 704, 708, 712, 716, -1, 720, -1, 724, 728, -1, -1, -1, -1, -1, -1}; + 664, 668, 672, 676, 680, -1, 684, -1, 688, 692, -1, -1, -1, -1, -1, -1}; static constexpr dart::compiler::target::word ApiError_InstanceSize = 8; static constexpr dart::compiler::target::word Array_InstanceSize = 12; static constexpr dart::compiler::target::word Array_header_size = 12; static constexpr dart::compiler::target::word Bool_InstanceSize = 8; -static constexpr dart::compiler::target::word Bytecode_InstanceSize = 44; static constexpr dart::compiler::target::word Capability_InstanceSize = 16; static constexpr dart::compiler::target::word Class_InstanceSize = 128; static constexpr dart::compiler::target::word Closure_InstanceSize = 28; @@ -2570,7 +2537,7 @@ static constexpr dart::compiler::target::word static constexpr dart::compiler::target::word Int32x4_InstanceSize = 24; static constexpr dart::compiler::target::word Integer_InstanceSize = 4; static constexpr dart::compiler::target::word KernelProgramInfo_InstanceSize = - 64; + 60; static constexpr dart::compiler::target::word LanguageError_InstanceSize = 28; static constexpr dart::compiler::target::word Library_InstanceSize = 84; static constexpr dart::compiler::target::word LibraryPrefix_InstanceSize = 20; @@ -2589,8 +2556,6 @@ static constexpr dart::compiler::target::word Number_InstanceSize = 4; static constexpr dart::compiler::target::word Object_InstanceSize = 4; static constexpr dart::compiler::target::word ObjectPool_InstanceSize = 8; static constexpr dart::compiler::target::word OneByteString_InstanceSize = 12; -static constexpr dart::compiler::target::word ParameterTypeCheck_InstanceSize = - 24; static constexpr dart::compiler::target::word PatchClass_InstanceSize = 24; static constexpr dart::compiler::target::word PcDescriptors_HeaderSize = 8; static constexpr dart::compiler::target::word Pointer_InstanceSize = 12; @@ -2827,160 +2792,156 @@ static constexpr dart::compiler::target::word String_hash_offset = 4; static constexpr dart::compiler::target::word String_length_offset = 8; static constexpr dart::compiler::target::word SubtypeTestCache_cache_offset = 8; static constexpr dart::compiler::target::word - Thread_AllocateArray_entry_point_offset = 752; + Thread_AllocateArray_entry_point_offset = 736; static constexpr dart::compiler::target::word Thread_active_exception_offset = - 1472; + 1400; static constexpr dart::compiler::target::word Thread_active_stacktrace_offset = - 1480; + 1408; static constexpr dart::compiler::target::word Thread_array_write_barrier_code_offset = 240; static constexpr dart::compiler::target::word - Thread_array_write_barrier_entry_point_offset = 536; + Thread_array_write_barrier_entry_point_offset = 528; static constexpr dart::compiler::target::word - Thread_allocate_mint_with_fpu_regs_entry_point_offset = 552; + Thread_allocate_mint_with_fpu_regs_entry_point_offset = 544; static constexpr dart::compiler::target::word - Thread_allocate_mint_with_fpu_regs_stub_offset = 368; + Thread_allocate_mint_with_fpu_regs_stub_offset = 360; static constexpr dart::compiler::target::word - Thread_allocate_mint_without_fpu_regs_entry_point_offset = 560; + Thread_allocate_mint_without_fpu_regs_entry_point_offset = 552; static constexpr dart::compiler::target::word - Thread_allocate_mint_without_fpu_regs_stub_offset = 376; + Thread_allocate_mint_without_fpu_regs_stub_offset = 368; static constexpr dart::compiler::target::word - Thread_allocate_object_entry_point_offset = 568; + Thread_allocate_object_entry_point_offset = 560; static constexpr dart::compiler::target::word - Thread_allocate_object_stub_offset = 384; + Thread_allocate_object_stub_offset = 376; static constexpr dart::compiler::target::word - Thread_allocate_object_parameterized_entry_point_offset = 576; + Thread_allocate_object_parameterized_entry_point_offset = 568; static constexpr dart::compiler::target::word - Thread_allocate_object_parameterized_stub_offset = 392; + Thread_allocate_object_parameterized_stub_offset = 384; static constexpr dart::compiler::target::word - Thread_allocate_object_slow_entry_point_offset = 584; + Thread_allocate_object_slow_entry_point_offset = 576; static constexpr dart::compiler::target::word - Thread_allocate_object_slow_stub_offset = 400; + Thread_allocate_object_slow_stub_offset = 392; static constexpr dart::compiler::target::word Thread_api_top_scope_offset = - 1544; + 1472; static constexpr dart::compiler::target::word Thread_async_stack_trace_offset = 192; static constexpr dart::compiler::target::word - Thread_auto_scope_native_wrapper_entry_point_offset = 672; + Thread_auto_scope_native_wrapper_entry_point_offset = 664; static constexpr dart::compiler::target::word Thread_bool_false_offset = 224; static constexpr dart::compiler::target::word Thread_bool_true_offset = 216; static constexpr dart::compiler::target::word - Thread_bootstrap_native_wrapper_entry_point_offset = 656; + Thread_bootstrap_native_wrapper_entry_point_offset = 648; static constexpr dart::compiler::target::word - Thread_call_to_runtime_entry_point_offset = 544; + Thread_call_to_runtime_entry_point_offset = 536; static constexpr dart::compiler::target::word - Thread_call_to_runtime_stub_offset = 280; -static constexpr dart::compiler::target::word Thread_dart_stream_offset = 1560; + Thread_call_to_runtime_stub_offset = 272; +static constexpr dart::compiler::target::word Thread_dart_stream_offset = 1488; static constexpr dart::compiler::target::word Thread_dispatch_table_array_offset = 96; static constexpr dart::compiler::target::word Thread_optimize_entry_offset = - 624; -static constexpr dart::compiler::target::word Thread_optimize_stub_offset = 456; + 616; +static constexpr dart::compiler::target::word Thread_optimize_stub_offset = 448; static constexpr dart::compiler::target::word Thread_deoptimize_entry_offset = - 632; + 624; static constexpr dart::compiler::target::word Thread_deoptimize_stub_offset = - 464; + 456; static constexpr dart::compiler::target::word Thread_double_abs_address_offset = - 712; + 696; static constexpr dart::compiler::target::word - Thread_double_negate_address_offset = 704; + Thread_double_negate_address_offset = 688; static constexpr dart::compiler::target::word Thread_end_offset = 112; static constexpr dart::compiler::target::word - Thread_enter_safepoint_stub_offset = 504; + Thread_enter_safepoint_stub_offset = 496; static constexpr dart::compiler::target::word Thread_execution_state_offset = - 1512; + 1440; static constexpr dart::compiler::target::word - Thread_exit_safepoint_stub_offset = 512; + Thread_exit_safepoint_stub_offset = 504; static constexpr dart::compiler::target::word - Thread_call_native_through_safepoint_stub_offset = 520; + Thread_call_native_through_safepoint_stub_offset = 512; static constexpr dart::compiler::target::word - Thread_call_native_through_safepoint_entry_point_offset = 640; + Thread_call_native_through_safepoint_entry_point_offset = 632; static constexpr dart::compiler::target::word Thread_fix_allocation_stub_code_offset = 256; static constexpr dart::compiler::target::word Thread_fix_callers_target_code_offset = 248; static constexpr dart::compiler::target::word - Thread_float_absolute_address_offset = 736; + Thread_float_absolute_address_offset = 720; static constexpr dart::compiler::target::word - Thread_float_negate_address_offset = 728; + Thread_float_negate_address_offset = 712; static constexpr dart::compiler::target::word Thread_float_not_address_offset = - 720; + 704; static constexpr dart::compiler::target::word - Thread_float_zerow_address_offset = 744; + Thread_float_zerow_address_offset = 728; static constexpr dart::compiler::target::word Thread_global_object_pool_offset = - 1488; -static constexpr dart::compiler::target::word - Thread_interpret_call_entry_point_offset = 680; -static constexpr dart::compiler::target::word - Thread_invoke_dart_code_from_bytecode_stub_offset = 272; + 1416; static constexpr dart::compiler::target::word Thread_invoke_dart_code_stub_offset = 264; static constexpr dart::compiler::target::word Thread_exit_through_ffi_offset = - 1536; + 1464; static constexpr dart::compiler::target::word Thread_isolate_offset = 88; static constexpr dart::compiler::target::word Thread_field_table_values_offset = 136; static constexpr dart::compiler::target::word - Thread_lazy_deopt_from_return_stub_offset = 472; + Thread_lazy_deopt_from_return_stub_offset = 464; static constexpr dart::compiler::target::word - Thread_lazy_deopt_from_throw_stub_offset = 480; + Thread_lazy_deopt_from_throw_stub_offset = 472; static constexpr dart::compiler::target::word - Thread_lazy_specialize_type_test_stub_offset = 496; + Thread_lazy_specialize_type_test_stub_offset = 488; static constexpr dart::compiler::target::word Thread_marking_stack_block_offset = 168; static constexpr dart::compiler::target::word - Thread_megamorphic_call_checked_entry_offset = 608; + Thread_megamorphic_call_checked_entry_offset = 600; static constexpr dart::compiler::target::word - Thread_switchable_call_miss_entry_offset = 616; + Thread_switchable_call_miss_entry_offset = 608; static constexpr dart::compiler::target::word - Thread_switchable_call_miss_stub_offset = 424; + Thread_switchable_call_miss_stub_offset = 416; static constexpr dart::compiler::target::word - Thread_no_scope_native_wrapper_entry_point_offset = 664; + Thread_no_scope_native_wrapper_entry_point_offset = 656; static constexpr dart::compiler::target::word - Thread_late_initialization_error_shared_with_fpu_regs_stub_offset = 296; + Thread_late_initialization_error_shared_with_fpu_regs_stub_offset = 288; static constexpr dart::compiler::target::word - Thread_late_initialization_error_shared_without_fpu_regs_stub_offset = 288; + Thread_late_initialization_error_shared_without_fpu_regs_stub_offset = 280; static constexpr dart::compiler::target::word - Thread_null_error_shared_with_fpu_regs_stub_offset = 312; + Thread_null_error_shared_with_fpu_regs_stub_offset = 304; static constexpr dart::compiler::target::word - Thread_null_error_shared_without_fpu_regs_stub_offset = 304; + Thread_null_error_shared_without_fpu_regs_stub_offset = 296; static constexpr dart::compiler::target::word - Thread_null_arg_error_shared_with_fpu_regs_stub_offset = 328; + Thread_null_arg_error_shared_with_fpu_regs_stub_offset = 320; static constexpr dart::compiler::target::word - Thread_null_arg_error_shared_without_fpu_regs_stub_offset = 320; + Thread_null_arg_error_shared_without_fpu_regs_stub_offset = 312; static constexpr dart::compiler::target::word - Thread_null_cast_error_shared_with_fpu_regs_stub_offset = 344; + Thread_null_cast_error_shared_with_fpu_regs_stub_offset = 336; static constexpr dart::compiler::target::word - Thread_null_cast_error_shared_without_fpu_regs_stub_offset = 336; + Thread_null_cast_error_shared_without_fpu_regs_stub_offset = 328; static constexpr dart::compiler::target::word - Thread_range_error_shared_with_fpu_regs_stub_offset = 360; + Thread_range_error_shared_with_fpu_regs_stub_offset = 352; static constexpr dart::compiler::target::word - Thread_range_error_shared_without_fpu_regs_stub_offset = 352; + Thread_range_error_shared_without_fpu_regs_stub_offset = 344; static constexpr dart::compiler::target::word Thread_object_null_offset = 208; static constexpr dart::compiler::target::word - Thread_predefined_symbols_address_offset = 688; -static constexpr dart::compiler::target::word Thread_resume_pc_offset = 1496; + Thread_predefined_symbols_address_offset = 672; +static constexpr dart::compiler::target::word Thread_resume_pc_offset = 1424; static constexpr dart::compiler::target::word - Thread_saved_shadow_call_stack_offset = 1504; + Thread_saved_shadow_call_stack_offset = 1432; static constexpr dart::compiler::target::word Thread_safepoint_state_offset = - 1520; + 1448; static constexpr dart::compiler::target::word - Thread_slow_type_test_stub_offset = 488; + Thread_slow_type_test_stub_offset = 480; static constexpr dart::compiler::target::word - Thread_slow_type_test_entry_point_offset = 648; + Thread_slow_type_test_entry_point_offset = 640; static constexpr dart::compiler::target::word Thread_stack_limit_offset = 72; static constexpr dart::compiler::target::word Thread_saved_stack_limit_offset = 120; static constexpr dart::compiler::target::word Thread_stack_overflow_flags_offset = 128; static constexpr dart::compiler::target::word - Thread_stack_overflow_shared_with_fpu_regs_entry_point_offset = 600; + Thread_stack_overflow_shared_with_fpu_regs_entry_point_offset = 592; static constexpr dart::compiler::target::word - Thread_stack_overflow_shared_with_fpu_regs_stub_offset = 416; + Thread_stack_overflow_shared_with_fpu_regs_stub_offset = 408; static constexpr dart::compiler::target::word - Thread_stack_overflow_shared_without_fpu_regs_entry_point_offset = 592; + Thread_stack_overflow_shared_without_fpu_regs_entry_point_offset = 584; static constexpr dart::compiler::target::word - Thread_stack_overflow_shared_without_fpu_regs_stub_offset = 408; + Thread_stack_overflow_shared_without_fpu_regs_stub_offset = 400; static constexpr dart::compiler::target::word Thread_store_buffer_block_offset = 160; static constexpr dart::compiler::target::word @@ -2993,11 +2954,11 @@ static constexpr dart::compiler::target::word Thread_vm_tag_offset = 184; static constexpr dart::compiler::target::word Thread_write_barrier_code_offset = 232; static constexpr dart::compiler::target::word - Thread_write_barrier_entry_point_offset = 528; + Thread_write_barrier_entry_point_offset = 520; static constexpr dart::compiler::target::word Thread_write_barrier_mask_offset = 80; static constexpr dart::compiler::target::word Thread_callback_code_offset = - 1528; + 1456; static constexpr dart::compiler::target::word TimelineStream_enabled_offset = 16; static constexpr dart::compiler::target::word TwoByteString_data_offset = 16; @@ -3045,13 +3006,12 @@ static constexpr dart::compiler::target::word Code_entry_point_offset[] = { 8, 24, 16, 32}; static constexpr dart::compiler::target::word Thread_write_barrier_wrappers_thread_offset[] = { - 1384, 1392, 1400, 1408, -1, -1, 1416, 1424, - 1432, 1440, 1448, -1, 1456, 1464, -1, -1}; + 1312, 1320, 1328, 1336, -1, -1, 1344, 1352, + 1360, 1368, 1376, -1, 1384, 1392, -1, -1}; static constexpr dart::compiler::target::word ApiError_InstanceSize = 16; static constexpr dart::compiler::target::word Array_InstanceSize = 24; static constexpr dart::compiler::target::word Array_header_size = 24; static constexpr dart::compiler::target::word Bool_InstanceSize = 12; -static constexpr dart::compiler::target::word Bytecode_InstanceSize = 80; static constexpr dart::compiler::target::word Capability_InstanceSize = 16; static constexpr dart::compiler::target::word Class_InstanceSize = 208; static constexpr dart::compiler::target::word Closure_InstanceSize = 56; @@ -3078,7 +3038,7 @@ static constexpr dart::compiler::target::word FfiTrampolineData_InstanceSize = static constexpr dart::compiler::target::word Field_InstanceSize = 104; static constexpr dart::compiler::target::word Float32x4_InstanceSize = 24; static constexpr dart::compiler::target::word Float64x2_InstanceSize = 24; -static constexpr dart::compiler::target::word Function_InstanceSize = 152; +static constexpr dart::compiler::target::word Function_InstanceSize = 144; static constexpr dart::compiler::target::word FutureOr_InstanceSize = 16; static constexpr dart::compiler::target::word GrowableObjectArray_InstanceSize = 32; @@ -3091,7 +3051,7 @@ static constexpr dart::compiler::target::word static constexpr dart::compiler::target::word Int32x4_InstanceSize = 24; static constexpr dart::compiler::target::word Integer_InstanceSize = 8; static constexpr dart::compiler::target::word KernelProgramInfo_InstanceSize = - 128; + 120; static constexpr dart::compiler::target::word LanguageError_InstanceSize = 48; static constexpr dart::compiler::target::word Library_InstanceSize = 160; static constexpr dart::compiler::target::word LibraryPrefix_InstanceSize = 40; @@ -3110,8 +3070,6 @@ static constexpr dart::compiler::target::word Number_InstanceSize = 8; static constexpr dart::compiler::target::word Object_InstanceSize = 8; static constexpr dart::compiler::target::word ObjectPool_InstanceSize = 16; static constexpr dart::compiler::target::word OneByteString_InstanceSize = 16; -static constexpr dart::compiler::target::word ParameterTypeCheck_InstanceSize = - 48; static constexpr dart::compiler::target::word PatchClass_InstanceSize = 48; static constexpr dart::compiler::target::word PcDescriptors_HeaderSize = 16; static constexpr dart::compiler::target::word Pointer_InstanceSize = 24; @@ -3151,7 +3109,7 @@ static constexpr dart::compiler::target::word #if defined(TARGET_ARCH_IA32) static constexpr dart::compiler::target::word Function_usage_counter_offset = - 76; + 84; static constexpr dart::compiler::target::word ICData_receivers_static_type_offset = 16; static constexpr dart::compiler::target::word ObjectPool_elements_start_offset = @@ -3263,9 +3221,9 @@ static constexpr dart::compiler::target::word Function_code_offset = 44; static constexpr dart::compiler::target::word Function_data_offset = 36; static constexpr dart::compiler::target::word Function_entry_point_offset[] = { 4, 8}; -static constexpr dart::compiler::target::word Function_kind_tag_offset = 64; +static constexpr dart::compiler::target::word Function_kind_tag_offset = 72; static constexpr dart::compiler::target::word Function_packed_fields_offset = - 68; + 76; static constexpr dart::compiler::target::word Function_parameter_names_offset = 28; static constexpr dart::compiler::target::word Function_parameter_types_offset = @@ -3346,159 +3304,155 @@ static constexpr dart::compiler::target::word String_hash_offset = 8; static constexpr dart::compiler::target::word String_length_offset = 4; static constexpr dart::compiler::target::word SubtypeTestCache_cache_offset = 4; static constexpr dart::compiler::target::word - Thread_AllocateArray_entry_point_offset = 384; + Thread_AllocateArray_entry_point_offset = 376; static constexpr dart::compiler::target::word Thread_active_exception_offset = - 700; + 664; static constexpr dart::compiler::target::word Thread_active_stacktrace_offset = - 704; + 668; static constexpr dart::compiler::target::word Thread_array_write_barrier_code_offset = 128; static constexpr dart::compiler::target::word - Thread_array_write_barrier_entry_point_offset = 276; + Thread_array_write_barrier_entry_point_offset = 272; static constexpr dart::compiler::target::word - Thread_allocate_mint_with_fpu_regs_entry_point_offset = 284; + Thread_allocate_mint_with_fpu_regs_entry_point_offset = 280; static constexpr dart::compiler::target::word - Thread_allocate_mint_with_fpu_regs_stub_offset = 192; + Thread_allocate_mint_with_fpu_regs_stub_offset = 188; static constexpr dart::compiler::target::word - Thread_allocate_mint_without_fpu_regs_entry_point_offset = 288; + Thread_allocate_mint_without_fpu_regs_entry_point_offset = 284; static constexpr dart::compiler::target::word - Thread_allocate_mint_without_fpu_regs_stub_offset = 196; + Thread_allocate_mint_without_fpu_regs_stub_offset = 192; static constexpr dart::compiler::target::word - Thread_allocate_object_entry_point_offset = 292; + Thread_allocate_object_entry_point_offset = 288; static constexpr dart::compiler::target::word - Thread_allocate_object_stub_offset = 200; + Thread_allocate_object_stub_offset = 196; static constexpr dart::compiler::target::word - Thread_allocate_object_parameterized_entry_point_offset = 296; + Thread_allocate_object_parameterized_entry_point_offset = 292; static constexpr dart::compiler::target::word - Thread_allocate_object_parameterized_stub_offset = 204; + Thread_allocate_object_parameterized_stub_offset = 200; static constexpr dart::compiler::target::word - Thread_allocate_object_slow_entry_point_offset = 300; + Thread_allocate_object_slow_entry_point_offset = 296; static constexpr dart::compiler::target::word - Thread_allocate_object_slow_stub_offset = 208; -static constexpr dart::compiler::target::word Thread_api_top_scope_offset = 736; + Thread_allocate_object_slow_stub_offset = 204; +static constexpr dart::compiler::target::word Thread_api_top_scope_offset = 700; static constexpr dart::compiler::target::word Thread_async_stack_trace_offset = 96; static constexpr dart::compiler::target::word - Thread_auto_scope_native_wrapper_entry_point_offset = 344; + Thread_auto_scope_native_wrapper_entry_point_offset = 340; static constexpr dart::compiler::target::word Thread_bool_false_offset = 120; static constexpr dart::compiler::target::word Thread_bool_true_offset = 116; static constexpr dart::compiler::target::word - Thread_bootstrap_native_wrapper_entry_point_offset = 336; + Thread_bootstrap_native_wrapper_entry_point_offset = 332; static constexpr dart::compiler::target::word - Thread_call_to_runtime_entry_point_offset = 280; + Thread_call_to_runtime_entry_point_offset = 276; static constexpr dart::compiler::target::word - Thread_call_to_runtime_stub_offset = 148; -static constexpr dart::compiler::target::word Thread_dart_stream_offset = 744; + Thread_call_to_runtime_stub_offset = 144; +static constexpr dart::compiler::target::word Thread_dart_stream_offset = 708; static constexpr dart::compiler::target::word Thread_dispatch_table_array_offset = 48; static constexpr dart::compiler::target::word Thread_optimize_entry_offset = - 320; -static constexpr dart::compiler::target::word Thread_optimize_stub_offset = 236; + 316; +static constexpr dart::compiler::target::word Thread_optimize_stub_offset = 232; static constexpr dart::compiler::target::word Thread_deoptimize_entry_offset = - 324; + 320; static constexpr dart::compiler::target::word Thread_deoptimize_stub_offset = - 240; + 236; static constexpr dart::compiler::target::word Thread_double_abs_address_offset = - 364; + 356; static constexpr dart::compiler::target::word - Thread_double_negate_address_offset = 360; + Thread_double_negate_address_offset = 352; static constexpr dart::compiler::target::word Thread_end_offset = 56; static constexpr dart::compiler::target::word - Thread_enter_safepoint_stub_offset = 260; + Thread_enter_safepoint_stub_offset = 256; static constexpr dart::compiler::target::word Thread_execution_state_offset = - 720; + 684; static constexpr dart::compiler::target::word - Thread_exit_safepoint_stub_offset = 264; + Thread_exit_safepoint_stub_offset = 260; static constexpr dart::compiler::target::word - Thread_call_native_through_safepoint_stub_offset = 268; + Thread_call_native_through_safepoint_stub_offset = 264; static constexpr dart::compiler::target::word - Thread_call_native_through_safepoint_entry_point_offset = 328; + Thread_call_native_through_safepoint_entry_point_offset = 324; static constexpr dart::compiler::target::word Thread_fix_allocation_stub_code_offset = 136; static constexpr dart::compiler::target::word Thread_fix_callers_target_code_offset = 132; static constexpr dart::compiler::target::word - Thread_float_absolute_address_offset = 376; + Thread_float_absolute_address_offset = 368; static constexpr dart::compiler::target::word - Thread_float_negate_address_offset = 372; + Thread_float_negate_address_offset = 364; static constexpr dart::compiler::target::word Thread_float_not_address_offset = - 368; + 360; static constexpr dart::compiler::target::word - Thread_float_zerow_address_offset = 380; + Thread_float_zerow_address_offset = 372; static constexpr dart::compiler::target::word Thread_global_object_pool_offset = - 708; -static constexpr dart::compiler::target::word - Thread_interpret_call_entry_point_offset = 348; -static constexpr dart::compiler::target::word - Thread_invoke_dart_code_from_bytecode_stub_offset = 144; + 672; static constexpr dart::compiler::target::word Thread_invoke_dart_code_stub_offset = 140; static constexpr dart::compiler::target::word Thread_exit_through_ffi_offset = - 732; + 696; static constexpr dart::compiler::target::word Thread_isolate_offset = 44; static constexpr dart::compiler::target::word Thread_field_table_values_offset = 68; static constexpr dart::compiler::target::word - Thread_lazy_deopt_from_return_stub_offset = 244; + Thread_lazy_deopt_from_return_stub_offset = 240; static constexpr dart::compiler::target::word - Thread_lazy_deopt_from_throw_stub_offset = 248; + Thread_lazy_deopt_from_throw_stub_offset = 244; static constexpr dart::compiler::target::word - Thread_lazy_specialize_type_test_stub_offset = 256; + Thread_lazy_specialize_type_test_stub_offset = 252; static constexpr dart::compiler::target::word Thread_marking_stack_block_offset = 84; static constexpr dart::compiler::target::word - Thread_megamorphic_call_checked_entry_offset = 312; + Thread_megamorphic_call_checked_entry_offset = 308; static constexpr dart::compiler::target::word - Thread_switchable_call_miss_entry_offset = 316; + Thread_switchable_call_miss_entry_offset = 312; static constexpr dart::compiler::target::word - Thread_switchable_call_miss_stub_offset = 220; + Thread_switchable_call_miss_stub_offset = 216; static constexpr dart::compiler::target::word - Thread_no_scope_native_wrapper_entry_point_offset = 340; + Thread_no_scope_native_wrapper_entry_point_offset = 336; static constexpr dart::compiler::target::word - Thread_late_initialization_error_shared_with_fpu_regs_stub_offset = 156; + Thread_late_initialization_error_shared_with_fpu_regs_stub_offset = 152; static constexpr dart::compiler::target::word - Thread_late_initialization_error_shared_without_fpu_regs_stub_offset = 152; + Thread_late_initialization_error_shared_without_fpu_regs_stub_offset = 148; static constexpr dart::compiler::target::word - Thread_null_error_shared_with_fpu_regs_stub_offset = 164; + Thread_null_error_shared_with_fpu_regs_stub_offset = 160; static constexpr dart::compiler::target::word - Thread_null_error_shared_without_fpu_regs_stub_offset = 160; + Thread_null_error_shared_without_fpu_regs_stub_offset = 156; static constexpr dart::compiler::target::word - Thread_null_arg_error_shared_with_fpu_regs_stub_offset = 172; + Thread_null_arg_error_shared_with_fpu_regs_stub_offset = 168; static constexpr dart::compiler::target::word - Thread_null_arg_error_shared_without_fpu_regs_stub_offset = 168; + Thread_null_arg_error_shared_without_fpu_regs_stub_offset = 164; static constexpr dart::compiler::target::word - Thread_null_cast_error_shared_with_fpu_regs_stub_offset = 180; + Thread_null_cast_error_shared_with_fpu_regs_stub_offset = 176; static constexpr dart::compiler::target::word - Thread_null_cast_error_shared_without_fpu_regs_stub_offset = 176; + Thread_null_cast_error_shared_without_fpu_regs_stub_offset = 172; static constexpr dart::compiler::target::word - Thread_range_error_shared_with_fpu_regs_stub_offset = 188; + Thread_range_error_shared_with_fpu_regs_stub_offset = 184; static constexpr dart::compiler::target::word - Thread_range_error_shared_without_fpu_regs_stub_offset = 184; + Thread_range_error_shared_without_fpu_regs_stub_offset = 180; static constexpr dart::compiler::target::word Thread_object_null_offset = 112; static constexpr dart::compiler::target::word - Thread_predefined_symbols_address_offset = 352; -static constexpr dart::compiler::target::word Thread_resume_pc_offset = 712; + Thread_predefined_symbols_address_offset = 344; +static constexpr dart::compiler::target::word Thread_resume_pc_offset = 676; static constexpr dart::compiler::target::word - Thread_saved_shadow_call_stack_offset = 716; + Thread_saved_shadow_call_stack_offset = 680; static constexpr dart::compiler::target::word Thread_safepoint_state_offset = - 724; + 688; static constexpr dart::compiler::target::word - Thread_slow_type_test_stub_offset = 252; + Thread_slow_type_test_stub_offset = 248; static constexpr dart::compiler::target::word - Thread_slow_type_test_entry_point_offset = 332; + Thread_slow_type_test_entry_point_offset = 328; static constexpr dart::compiler::target::word Thread_stack_limit_offset = 36; static constexpr dart::compiler::target::word Thread_saved_stack_limit_offset = 60; static constexpr dart::compiler::target::word Thread_stack_overflow_flags_offset = 64; static constexpr dart::compiler::target::word - Thread_stack_overflow_shared_with_fpu_regs_entry_point_offset = 308; + Thread_stack_overflow_shared_with_fpu_regs_entry_point_offset = 304; static constexpr dart::compiler::target::word - Thread_stack_overflow_shared_with_fpu_regs_stub_offset = 216; + Thread_stack_overflow_shared_with_fpu_regs_stub_offset = 212; static constexpr dart::compiler::target::word - Thread_stack_overflow_shared_without_fpu_regs_entry_point_offset = 304; + Thread_stack_overflow_shared_without_fpu_regs_entry_point_offset = 300; static constexpr dart::compiler::target::word - Thread_stack_overflow_shared_without_fpu_regs_stub_offset = 212; + Thread_stack_overflow_shared_without_fpu_regs_stub_offset = 208; static constexpr dart::compiler::target::word Thread_store_buffer_block_offset = 80; static constexpr dart::compiler::target::word @@ -3511,10 +3465,10 @@ static constexpr dart::compiler::target::word Thread_vm_tag_offset = 92; static constexpr dart::compiler::target::word Thread_write_barrier_code_offset = 124; static constexpr dart::compiler::target::word - Thread_write_barrier_entry_point_offset = 272; + Thread_write_barrier_entry_point_offset = 268; static constexpr dart::compiler::target::word Thread_write_barrier_mask_offset = 40; -static constexpr dart::compiler::target::word Thread_callback_code_offset = 728; +static constexpr dart::compiler::target::word Thread_callback_code_offset = 692; static constexpr dart::compiler::target::word TimelineStream_enabled_offset = 8; static constexpr dart::compiler::target::word TwoByteString_data_offset = 12; static constexpr dart::compiler::target::word Type_arguments_offset = 16; @@ -3563,7 +3517,6 @@ static constexpr dart::compiler::target::word ApiError_InstanceSize = 8; static constexpr dart::compiler::target::word Array_InstanceSize = 12; static constexpr dart::compiler::target::word Array_header_size = 12; static constexpr dart::compiler::target::word Bool_InstanceSize = 8; -static constexpr dart::compiler::target::word Bytecode_InstanceSize = 44; static constexpr dart::compiler::target::word Capability_InstanceSize = 16; static constexpr dart::compiler::target::word Class_InstanceSize = 128; static constexpr dart::compiler::target::word Closure_InstanceSize = 28; @@ -3603,7 +3556,7 @@ static constexpr dart::compiler::target::word static constexpr dart::compiler::target::word Int32x4_InstanceSize = 24; static constexpr dart::compiler::target::word Integer_InstanceSize = 4; static constexpr dart::compiler::target::word KernelProgramInfo_InstanceSize = - 64; + 60; static constexpr dart::compiler::target::word LanguageError_InstanceSize = 28; static constexpr dart::compiler::target::word Library_InstanceSize = 84; static constexpr dart::compiler::target::word LibraryPrefix_InstanceSize = 20; @@ -3622,8 +3575,6 @@ static constexpr dart::compiler::target::word Number_InstanceSize = 4; static constexpr dart::compiler::target::word Object_InstanceSize = 4; static constexpr dart::compiler::target::word ObjectPool_InstanceSize = 8; static constexpr dart::compiler::target::word OneByteString_InstanceSize = 12; -static constexpr dart::compiler::target::word ParameterTypeCheck_InstanceSize = - 24; static constexpr dart::compiler::target::word PatchClass_InstanceSize = 24; static constexpr dart::compiler::target::word PcDescriptors_HeaderSize = 8; static constexpr dart::compiler::target::word Pointer_InstanceSize = 12; @@ -3860,160 +3811,156 @@ static constexpr dart::compiler::target::word String_hash_offset = 4; static constexpr dart::compiler::target::word String_length_offset = 8; static constexpr dart::compiler::target::word SubtypeTestCache_cache_offset = 8; static constexpr dart::compiler::target::word - Thread_AllocateArray_entry_point_offset = 752; + Thread_AllocateArray_entry_point_offset = 736; static constexpr dart::compiler::target::word Thread_active_exception_offset = - 1544; + 1472; static constexpr dart::compiler::target::word Thread_active_stacktrace_offset = - 1552; + 1480; static constexpr dart::compiler::target::word Thread_array_write_barrier_code_offset = 240; static constexpr dart::compiler::target::word - Thread_array_write_barrier_entry_point_offset = 536; + Thread_array_write_barrier_entry_point_offset = 528; static constexpr dart::compiler::target::word - Thread_allocate_mint_with_fpu_regs_entry_point_offset = 552; + Thread_allocate_mint_with_fpu_regs_entry_point_offset = 544; static constexpr dart::compiler::target::word - Thread_allocate_mint_with_fpu_regs_stub_offset = 368; + Thread_allocate_mint_with_fpu_regs_stub_offset = 360; static constexpr dart::compiler::target::word - Thread_allocate_mint_without_fpu_regs_entry_point_offset = 560; + Thread_allocate_mint_without_fpu_regs_entry_point_offset = 552; static constexpr dart::compiler::target::word - Thread_allocate_mint_without_fpu_regs_stub_offset = 376; + Thread_allocate_mint_without_fpu_regs_stub_offset = 368; static constexpr dart::compiler::target::word - Thread_allocate_object_entry_point_offset = 568; + Thread_allocate_object_entry_point_offset = 560; static constexpr dart::compiler::target::word - Thread_allocate_object_stub_offset = 384; + Thread_allocate_object_stub_offset = 376; static constexpr dart::compiler::target::word - Thread_allocate_object_parameterized_entry_point_offset = 576; + Thread_allocate_object_parameterized_entry_point_offset = 568; static constexpr dart::compiler::target::word - Thread_allocate_object_parameterized_stub_offset = 392; + Thread_allocate_object_parameterized_stub_offset = 384; static constexpr dart::compiler::target::word - Thread_allocate_object_slow_entry_point_offset = 584; + Thread_allocate_object_slow_entry_point_offset = 576; static constexpr dart::compiler::target::word - Thread_allocate_object_slow_stub_offset = 400; + Thread_allocate_object_slow_stub_offset = 392; static constexpr dart::compiler::target::word Thread_api_top_scope_offset = - 1616; + 1544; static constexpr dart::compiler::target::word Thread_async_stack_trace_offset = 192; static constexpr dart::compiler::target::word - Thread_auto_scope_native_wrapper_entry_point_offset = 672; + Thread_auto_scope_native_wrapper_entry_point_offset = 664; static constexpr dart::compiler::target::word Thread_bool_false_offset = 224; static constexpr dart::compiler::target::word Thread_bool_true_offset = 216; static constexpr dart::compiler::target::word - Thread_bootstrap_native_wrapper_entry_point_offset = 656; + Thread_bootstrap_native_wrapper_entry_point_offset = 648; static constexpr dart::compiler::target::word - Thread_call_to_runtime_entry_point_offset = 544; + Thread_call_to_runtime_entry_point_offset = 536; static constexpr dart::compiler::target::word - Thread_call_to_runtime_stub_offset = 280; -static constexpr dart::compiler::target::word Thread_dart_stream_offset = 1632; + Thread_call_to_runtime_stub_offset = 272; +static constexpr dart::compiler::target::word Thread_dart_stream_offset = 1560; static constexpr dart::compiler::target::word Thread_dispatch_table_array_offset = 96; static constexpr dart::compiler::target::word Thread_optimize_entry_offset = - 624; -static constexpr dart::compiler::target::word Thread_optimize_stub_offset = 456; + 616; +static constexpr dart::compiler::target::word Thread_optimize_stub_offset = 448; static constexpr dart::compiler::target::word Thread_deoptimize_entry_offset = - 632; + 624; static constexpr dart::compiler::target::word Thread_deoptimize_stub_offset = - 464; + 456; static constexpr dart::compiler::target::word Thread_double_abs_address_offset = - 712; + 696; static constexpr dart::compiler::target::word - Thread_double_negate_address_offset = 704; + Thread_double_negate_address_offset = 688; static constexpr dart::compiler::target::word Thread_end_offset = 112; static constexpr dart::compiler::target::word - Thread_enter_safepoint_stub_offset = 504; + Thread_enter_safepoint_stub_offset = 496; static constexpr dart::compiler::target::word Thread_execution_state_offset = - 1584; + 1512; static constexpr dart::compiler::target::word - Thread_exit_safepoint_stub_offset = 512; + Thread_exit_safepoint_stub_offset = 504; static constexpr dart::compiler::target::word - Thread_call_native_through_safepoint_stub_offset = 520; + Thread_call_native_through_safepoint_stub_offset = 512; static constexpr dart::compiler::target::word - Thread_call_native_through_safepoint_entry_point_offset = 640; + Thread_call_native_through_safepoint_entry_point_offset = 632; static constexpr dart::compiler::target::word Thread_fix_allocation_stub_code_offset = 256; static constexpr dart::compiler::target::word Thread_fix_callers_target_code_offset = 248; static constexpr dart::compiler::target::word - Thread_float_absolute_address_offset = 736; + Thread_float_absolute_address_offset = 720; static constexpr dart::compiler::target::word - Thread_float_negate_address_offset = 728; + Thread_float_negate_address_offset = 712; static constexpr dart::compiler::target::word Thread_float_not_address_offset = - 720; + 704; static constexpr dart::compiler::target::word - Thread_float_zerow_address_offset = 744; + Thread_float_zerow_address_offset = 728; static constexpr dart::compiler::target::word Thread_global_object_pool_offset = - 1560; -static constexpr dart::compiler::target::word - Thread_interpret_call_entry_point_offset = 680; -static constexpr dart::compiler::target::word - Thread_invoke_dart_code_from_bytecode_stub_offset = 272; + 1488; static constexpr dart::compiler::target::word Thread_invoke_dart_code_stub_offset = 264; static constexpr dart::compiler::target::word Thread_exit_through_ffi_offset = - 1608; + 1536; static constexpr dart::compiler::target::word Thread_isolate_offset = 88; static constexpr dart::compiler::target::word Thread_field_table_values_offset = 136; static constexpr dart::compiler::target::word - Thread_lazy_deopt_from_return_stub_offset = 472; + Thread_lazy_deopt_from_return_stub_offset = 464; static constexpr dart::compiler::target::word - Thread_lazy_deopt_from_throw_stub_offset = 480; + Thread_lazy_deopt_from_throw_stub_offset = 472; static constexpr dart::compiler::target::word - Thread_lazy_specialize_type_test_stub_offset = 496; + Thread_lazy_specialize_type_test_stub_offset = 488; static constexpr dart::compiler::target::word Thread_marking_stack_block_offset = 168; static constexpr dart::compiler::target::word - Thread_megamorphic_call_checked_entry_offset = 608; + Thread_megamorphic_call_checked_entry_offset = 600; static constexpr dart::compiler::target::word - Thread_switchable_call_miss_entry_offset = 616; + Thread_switchable_call_miss_entry_offset = 608; static constexpr dart::compiler::target::word - Thread_switchable_call_miss_stub_offset = 424; + Thread_switchable_call_miss_stub_offset = 416; static constexpr dart::compiler::target::word - Thread_no_scope_native_wrapper_entry_point_offset = 664; + Thread_no_scope_native_wrapper_entry_point_offset = 656; static constexpr dart::compiler::target::word - Thread_late_initialization_error_shared_with_fpu_regs_stub_offset = 296; + Thread_late_initialization_error_shared_with_fpu_regs_stub_offset = 288; static constexpr dart::compiler::target::word - Thread_late_initialization_error_shared_without_fpu_regs_stub_offset = 288; + Thread_late_initialization_error_shared_without_fpu_regs_stub_offset = 280; static constexpr dart::compiler::target::word - Thread_null_error_shared_with_fpu_regs_stub_offset = 312; + Thread_null_error_shared_with_fpu_regs_stub_offset = 304; static constexpr dart::compiler::target::word - Thread_null_error_shared_without_fpu_regs_stub_offset = 304; + Thread_null_error_shared_without_fpu_regs_stub_offset = 296; static constexpr dart::compiler::target::word - Thread_null_arg_error_shared_with_fpu_regs_stub_offset = 328; + Thread_null_arg_error_shared_with_fpu_regs_stub_offset = 320; static constexpr dart::compiler::target::word - Thread_null_arg_error_shared_without_fpu_regs_stub_offset = 320; + Thread_null_arg_error_shared_without_fpu_regs_stub_offset = 312; static constexpr dart::compiler::target::word - Thread_null_cast_error_shared_with_fpu_regs_stub_offset = 344; + Thread_null_cast_error_shared_with_fpu_regs_stub_offset = 336; static constexpr dart::compiler::target::word - Thread_null_cast_error_shared_without_fpu_regs_stub_offset = 336; + Thread_null_cast_error_shared_without_fpu_regs_stub_offset = 328; static constexpr dart::compiler::target::word - Thread_range_error_shared_with_fpu_regs_stub_offset = 360; + Thread_range_error_shared_with_fpu_regs_stub_offset = 352; static constexpr dart::compiler::target::word - Thread_range_error_shared_without_fpu_regs_stub_offset = 352; + Thread_range_error_shared_without_fpu_regs_stub_offset = 344; static constexpr dart::compiler::target::word Thread_object_null_offset = 208; static constexpr dart::compiler::target::word - Thread_predefined_symbols_address_offset = 688; -static constexpr dart::compiler::target::word Thread_resume_pc_offset = 1568; + Thread_predefined_symbols_address_offset = 672; +static constexpr dart::compiler::target::word Thread_resume_pc_offset = 1496; static constexpr dart::compiler::target::word - Thread_saved_shadow_call_stack_offset = 1576; + Thread_saved_shadow_call_stack_offset = 1504; static constexpr dart::compiler::target::word Thread_safepoint_state_offset = - 1592; + 1520; static constexpr dart::compiler::target::word - Thread_slow_type_test_stub_offset = 488; + Thread_slow_type_test_stub_offset = 480; static constexpr dart::compiler::target::word - Thread_slow_type_test_entry_point_offset = 648; + Thread_slow_type_test_entry_point_offset = 640; static constexpr dart::compiler::target::word Thread_stack_limit_offset = 72; static constexpr dart::compiler::target::word Thread_saved_stack_limit_offset = 120; static constexpr dart::compiler::target::word Thread_stack_overflow_flags_offset = 128; static constexpr dart::compiler::target::word - Thread_stack_overflow_shared_with_fpu_regs_entry_point_offset = 600; + Thread_stack_overflow_shared_with_fpu_regs_entry_point_offset = 592; static constexpr dart::compiler::target::word - Thread_stack_overflow_shared_with_fpu_regs_stub_offset = 416; + Thread_stack_overflow_shared_with_fpu_regs_stub_offset = 408; static constexpr dart::compiler::target::word - Thread_stack_overflow_shared_without_fpu_regs_entry_point_offset = 592; + Thread_stack_overflow_shared_without_fpu_regs_entry_point_offset = 584; static constexpr dart::compiler::target::word - Thread_stack_overflow_shared_without_fpu_regs_stub_offset = 408; + Thread_stack_overflow_shared_without_fpu_regs_stub_offset = 400; static constexpr dart::compiler::target::word Thread_store_buffer_block_offset = 160; static constexpr dart::compiler::target::word @@ -4026,11 +3973,11 @@ static constexpr dart::compiler::target::word Thread_vm_tag_offset = 184; static constexpr dart::compiler::target::word Thread_write_barrier_code_offset = 232; static constexpr dart::compiler::target::word - Thread_write_barrier_entry_point_offset = 528; + Thread_write_barrier_entry_point_offset = 520; static constexpr dart::compiler::target::word Thread_write_barrier_mask_offset = 80; static constexpr dart::compiler::target::word Thread_callback_code_offset = - 1600; + 1528; static constexpr dart::compiler::target::word TimelineStream_enabled_offset = 16; static constexpr dart::compiler::target::word TwoByteString_data_offset = 16; @@ -4078,14 +4025,13 @@ static constexpr dart::compiler::target::word Code_entry_point_offset[] = { 8, 24, 16, 32}; static constexpr dart::compiler::target::word Thread_write_barrier_wrappers_thread_offset[] = { - 1384, 1392, 1400, 1408, 1416, 1424, 1432, 1440, 1448, 1456, 1464, - 1472, 1480, 1488, 1496, -1, -1, -1, -1, 1504, 1512, -1, - -1, 1520, 1528, 1536, -1, -1, -1, -1, -1, -1}; + 1312, 1320, 1328, 1336, 1344, 1352, 1360, 1368, 1376, 1384, 1392, + 1400, 1408, 1416, 1424, -1, -1, -1, -1, 1432, 1440, -1, + -1, 1448, 1456, 1464, -1, -1, -1, -1, -1, -1}; static constexpr dart::compiler::target::word ApiError_InstanceSize = 16; static constexpr dart::compiler::target::word Array_InstanceSize = 24; static constexpr dart::compiler::target::word Array_header_size = 24; static constexpr dart::compiler::target::word Bool_InstanceSize = 12; -static constexpr dart::compiler::target::word Bytecode_InstanceSize = 80; static constexpr dart::compiler::target::word Capability_InstanceSize = 16; static constexpr dart::compiler::target::word Class_InstanceSize = 208; static constexpr dart::compiler::target::word Closure_InstanceSize = 56; @@ -4112,7 +4058,7 @@ static constexpr dart::compiler::target::word FfiTrampolineData_InstanceSize = static constexpr dart::compiler::target::word Field_InstanceSize = 104; static constexpr dart::compiler::target::word Float32x4_InstanceSize = 24; static constexpr dart::compiler::target::word Float64x2_InstanceSize = 24; -static constexpr dart::compiler::target::word Function_InstanceSize = 152; +static constexpr dart::compiler::target::word Function_InstanceSize = 144; static constexpr dart::compiler::target::word FutureOr_InstanceSize = 16; static constexpr dart::compiler::target::word GrowableObjectArray_InstanceSize = 32; @@ -4125,7 +4071,7 @@ static constexpr dart::compiler::target::word static constexpr dart::compiler::target::word Int32x4_InstanceSize = 24; static constexpr dart::compiler::target::word Integer_InstanceSize = 8; static constexpr dart::compiler::target::word KernelProgramInfo_InstanceSize = - 128; + 120; static constexpr dart::compiler::target::word LanguageError_InstanceSize = 48; static constexpr dart::compiler::target::word Library_InstanceSize = 160; static constexpr dart::compiler::target::word LibraryPrefix_InstanceSize = 40; @@ -4144,8 +4090,6 @@ static constexpr dart::compiler::target::word Number_InstanceSize = 8; static constexpr dart::compiler::target::word Object_InstanceSize = 8; static constexpr dart::compiler::target::word ObjectPool_InstanceSize = 16; static constexpr dart::compiler::target::word OneByteString_InstanceSize = 16; -static constexpr dart::compiler::target::word ParameterTypeCheck_InstanceSize = - 48; static constexpr dart::compiler::target::word PatchClass_InstanceSize = 48; static constexpr dart::compiler::target::word PcDescriptors_HeaderSize = 16; static constexpr dart::compiler::target::word Pointer_InstanceSize = 24; @@ -4405,152 +4349,148 @@ static constexpr dart::compiler::target::word AOT_String_length_offset = 4; static constexpr dart::compiler::target::word AOT_SubtypeTestCache_cache_offset = 4; static constexpr dart::compiler::target::word - AOT_Thread_AllocateArray_entry_point_offset = 384; + AOT_Thread_AllocateArray_entry_point_offset = 376; static constexpr dart::compiler::target::word - AOT_Thread_active_exception_offset = 732; + AOT_Thread_active_exception_offset = 696; static constexpr dart::compiler::target::word - AOT_Thread_active_stacktrace_offset = 736; + AOT_Thread_active_stacktrace_offset = 700; static constexpr dart::compiler::target::word AOT_Thread_array_write_barrier_code_offset = 128; static constexpr dart::compiler::target::word - AOT_Thread_array_write_barrier_entry_point_offset = 276; + AOT_Thread_array_write_barrier_entry_point_offset = 272; static constexpr dart::compiler::target::word - AOT_Thread_allocate_mint_with_fpu_regs_entry_point_offset = 284; + AOT_Thread_allocate_mint_with_fpu_regs_entry_point_offset = 280; static constexpr dart::compiler::target::word - AOT_Thread_allocate_mint_with_fpu_regs_stub_offset = 192; + AOT_Thread_allocate_mint_with_fpu_regs_stub_offset = 188; static constexpr dart::compiler::target::word - AOT_Thread_allocate_mint_without_fpu_regs_entry_point_offset = 288; + AOT_Thread_allocate_mint_without_fpu_regs_entry_point_offset = 284; static constexpr dart::compiler::target::word - AOT_Thread_allocate_mint_without_fpu_regs_stub_offset = 196; + AOT_Thread_allocate_mint_without_fpu_regs_stub_offset = 192; static constexpr dart::compiler::target::word - AOT_Thread_allocate_object_entry_point_offset = 292; + AOT_Thread_allocate_object_entry_point_offset = 288; static constexpr dart::compiler::target::word - AOT_Thread_allocate_object_stub_offset = 200; + AOT_Thread_allocate_object_stub_offset = 196; static constexpr dart::compiler::target::word - AOT_Thread_allocate_object_parameterized_entry_point_offset = 296; + AOT_Thread_allocate_object_parameterized_entry_point_offset = 292; static constexpr dart::compiler::target::word - AOT_Thread_allocate_object_parameterized_stub_offset = 204; + AOT_Thread_allocate_object_parameterized_stub_offset = 200; static constexpr dart::compiler::target::word - AOT_Thread_allocate_object_slow_entry_point_offset = 300; + AOT_Thread_allocate_object_slow_entry_point_offset = 296; static constexpr dart::compiler::target::word - AOT_Thread_allocate_object_slow_stub_offset = 208; + AOT_Thread_allocate_object_slow_stub_offset = 204; static constexpr dart::compiler::target::word AOT_Thread_api_top_scope_offset = - 768; + 732; static constexpr dart::compiler::target::word AOT_Thread_async_stack_trace_offset = 96; static constexpr dart::compiler::target::word - AOT_Thread_auto_scope_native_wrapper_entry_point_offset = 344; + AOT_Thread_auto_scope_native_wrapper_entry_point_offset = 340; static constexpr dart::compiler::target::word AOT_Thread_bool_false_offset = 120; static constexpr dart::compiler::target::word AOT_Thread_bool_true_offset = 116; static constexpr dart::compiler::target::word - AOT_Thread_bootstrap_native_wrapper_entry_point_offset = 336; + AOT_Thread_bootstrap_native_wrapper_entry_point_offset = 332; static constexpr dart::compiler::target::word - AOT_Thread_call_to_runtime_entry_point_offset = 280; + AOT_Thread_call_to_runtime_entry_point_offset = 276; static constexpr dart::compiler::target::word - AOT_Thread_call_to_runtime_stub_offset = 148; + AOT_Thread_call_to_runtime_stub_offset = 144; static constexpr dart::compiler::target::word AOT_Thread_dart_stream_offset = - 776; + 740; static constexpr dart::compiler::target::word AOT_Thread_dispatch_table_array_offset = 48; static constexpr dart::compiler::target::word AOT_Thread_optimize_entry_offset = - 320; + 316; static constexpr dart::compiler::target::word AOT_Thread_optimize_stub_offset = - 236; + 232; static constexpr dart::compiler::target::word - AOT_Thread_deoptimize_entry_offset = 324; + AOT_Thread_deoptimize_entry_offset = 320; static constexpr dart::compiler::target::word - AOT_Thread_deoptimize_stub_offset = 240; + AOT_Thread_deoptimize_stub_offset = 236; static constexpr dart::compiler::target::word - AOT_Thread_double_abs_address_offset = 364; + AOT_Thread_double_abs_address_offset = 356; static constexpr dart::compiler::target::word - AOT_Thread_double_negate_address_offset = 360; + AOT_Thread_double_negate_address_offset = 352; static constexpr dart::compiler::target::word AOT_Thread_end_offset = 56; static constexpr dart::compiler::target::word - AOT_Thread_enter_safepoint_stub_offset = 260; + AOT_Thread_enter_safepoint_stub_offset = 256; static constexpr dart::compiler::target::word - AOT_Thread_execution_state_offset = 752; + AOT_Thread_execution_state_offset = 716; static constexpr dart::compiler::target::word - AOT_Thread_exit_safepoint_stub_offset = 264; + AOT_Thread_exit_safepoint_stub_offset = 260; static constexpr dart::compiler::target::word - AOT_Thread_call_native_through_safepoint_stub_offset = 268; + AOT_Thread_call_native_through_safepoint_stub_offset = 264; static constexpr dart::compiler::target::word - AOT_Thread_call_native_through_safepoint_entry_point_offset = 328; + AOT_Thread_call_native_through_safepoint_entry_point_offset = 324; static constexpr dart::compiler::target::word AOT_Thread_fix_allocation_stub_code_offset = 136; static constexpr dart::compiler::target::word AOT_Thread_fix_callers_target_code_offset = 132; static constexpr dart::compiler::target::word - AOT_Thread_float_absolute_address_offset = 376; + AOT_Thread_float_absolute_address_offset = 368; static constexpr dart::compiler::target::word - AOT_Thread_float_negate_address_offset = 372; + AOT_Thread_float_negate_address_offset = 364; static constexpr dart::compiler::target::word - AOT_Thread_float_not_address_offset = 368; + AOT_Thread_float_not_address_offset = 360; static constexpr dart::compiler::target::word - AOT_Thread_float_zerow_address_offset = 380; + AOT_Thread_float_zerow_address_offset = 372; static constexpr dart::compiler::target::word - AOT_Thread_global_object_pool_offset = 740; -static constexpr dart::compiler::target::word - AOT_Thread_interpret_call_entry_point_offset = 348; -static constexpr dart::compiler::target::word - AOT_Thread_invoke_dart_code_from_bytecode_stub_offset = 144; + AOT_Thread_global_object_pool_offset = 704; static constexpr dart::compiler::target::word AOT_Thread_invoke_dart_code_stub_offset = 140; static constexpr dart::compiler::target::word - AOT_Thread_exit_through_ffi_offset = 764; + AOT_Thread_exit_through_ffi_offset = 728; static constexpr dart::compiler::target::word AOT_Thread_isolate_offset = 44; static constexpr dart::compiler::target::word AOT_Thread_field_table_values_offset = 68; static constexpr dart::compiler::target::word - AOT_Thread_lazy_deopt_from_return_stub_offset = 244; + AOT_Thread_lazy_deopt_from_return_stub_offset = 240; static constexpr dart::compiler::target::word - AOT_Thread_lazy_deopt_from_throw_stub_offset = 248; + AOT_Thread_lazy_deopt_from_throw_stub_offset = 244; static constexpr dart::compiler::target::word - AOT_Thread_lazy_specialize_type_test_stub_offset = 256; + AOT_Thread_lazy_specialize_type_test_stub_offset = 252; static constexpr dart::compiler::target::word AOT_Thread_marking_stack_block_offset = 84; static constexpr dart::compiler::target::word - AOT_Thread_megamorphic_call_checked_entry_offset = 312; + AOT_Thread_megamorphic_call_checked_entry_offset = 308; static constexpr dart::compiler::target::word - AOT_Thread_switchable_call_miss_entry_offset = 316; + AOT_Thread_switchable_call_miss_entry_offset = 312; static constexpr dart::compiler::target::word - AOT_Thread_switchable_call_miss_stub_offset = 220; + AOT_Thread_switchable_call_miss_stub_offset = 216; static constexpr dart::compiler::target::word - AOT_Thread_no_scope_native_wrapper_entry_point_offset = 340; + AOT_Thread_no_scope_native_wrapper_entry_point_offset = 336; static constexpr dart::compiler::target::word - AOT_Thread_late_initialization_error_shared_with_fpu_regs_stub_offset = 156; + AOT_Thread_late_initialization_error_shared_with_fpu_regs_stub_offset = 152; static constexpr dart::compiler::target::word AOT_Thread_late_initialization_error_shared_without_fpu_regs_stub_offset = - 152; + 148; static constexpr dart::compiler::target::word - AOT_Thread_null_error_shared_with_fpu_regs_stub_offset = 164; + AOT_Thread_null_error_shared_with_fpu_regs_stub_offset = 160; static constexpr dart::compiler::target::word - AOT_Thread_null_error_shared_without_fpu_regs_stub_offset = 160; + AOT_Thread_null_error_shared_without_fpu_regs_stub_offset = 156; static constexpr dart::compiler::target::word - AOT_Thread_null_arg_error_shared_with_fpu_regs_stub_offset = 172; + AOT_Thread_null_arg_error_shared_with_fpu_regs_stub_offset = 168; static constexpr dart::compiler::target::word - AOT_Thread_null_arg_error_shared_without_fpu_regs_stub_offset = 168; + AOT_Thread_null_arg_error_shared_without_fpu_regs_stub_offset = 164; static constexpr dart::compiler::target::word - AOT_Thread_null_cast_error_shared_with_fpu_regs_stub_offset = 180; + AOT_Thread_null_cast_error_shared_with_fpu_regs_stub_offset = 176; static constexpr dart::compiler::target::word - AOT_Thread_null_cast_error_shared_without_fpu_regs_stub_offset = 176; + AOT_Thread_null_cast_error_shared_without_fpu_regs_stub_offset = 172; static constexpr dart::compiler::target::word - AOT_Thread_range_error_shared_with_fpu_regs_stub_offset = 188; + AOT_Thread_range_error_shared_with_fpu_regs_stub_offset = 184; static constexpr dart::compiler::target::word - AOT_Thread_range_error_shared_without_fpu_regs_stub_offset = 184; + AOT_Thread_range_error_shared_without_fpu_regs_stub_offset = 180; static constexpr dart::compiler::target::word AOT_Thread_object_null_offset = 112; static constexpr dart::compiler::target::word - AOT_Thread_predefined_symbols_address_offset = 352; -static constexpr dart::compiler::target::word AOT_Thread_resume_pc_offset = 744; + AOT_Thread_predefined_symbols_address_offset = 344; +static constexpr dart::compiler::target::word AOT_Thread_resume_pc_offset = 708; static constexpr dart::compiler::target::word - AOT_Thread_saved_shadow_call_stack_offset = 748; + AOT_Thread_saved_shadow_call_stack_offset = 712; static constexpr dart::compiler::target::word - AOT_Thread_safepoint_state_offset = 756; + AOT_Thread_safepoint_state_offset = 720; static constexpr dart::compiler::target::word - AOT_Thread_slow_type_test_stub_offset = 252; + AOT_Thread_slow_type_test_stub_offset = 248; static constexpr dart::compiler::target::word - AOT_Thread_slow_type_test_entry_point_offset = 332; + AOT_Thread_slow_type_test_entry_point_offset = 328; static constexpr dart::compiler::target::word AOT_Thread_stack_limit_offset = 36; static constexpr dart::compiler::target::word @@ -4558,13 +4498,13 @@ static constexpr dart::compiler::target::word static constexpr dart::compiler::target::word AOT_Thread_stack_overflow_flags_offset = 64; static constexpr dart::compiler::target::word - AOT_Thread_stack_overflow_shared_with_fpu_regs_entry_point_offset = 308; + AOT_Thread_stack_overflow_shared_with_fpu_regs_entry_point_offset = 304; static constexpr dart::compiler::target::word - AOT_Thread_stack_overflow_shared_with_fpu_regs_stub_offset = 216; + AOT_Thread_stack_overflow_shared_with_fpu_regs_stub_offset = 212; static constexpr dart::compiler::target::word - AOT_Thread_stack_overflow_shared_without_fpu_regs_entry_point_offset = 304; + AOT_Thread_stack_overflow_shared_without_fpu_regs_entry_point_offset = 300; static constexpr dart::compiler::target::word - AOT_Thread_stack_overflow_shared_without_fpu_regs_stub_offset = 212; + AOT_Thread_stack_overflow_shared_without_fpu_regs_stub_offset = 208; static constexpr dart::compiler::target::word AOT_Thread_store_buffer_block_offset = 80; static constexpr dart::compiler::target::word @@ -4578,11 +4518,11 @@ static constexpr dart::compiler::target::word AOT_Thread_vm_tag_offset = 92; static constexpr dart::compiler::target::word AOT_Thread_write_barrier_code_offset = 124; static constexpr dart::compiler::target::word - AOT_Thread_write_barrier_entry_point_offset = 272; + AOT_Thread_write_barrier_entry_point_offset = 268; static constexpr dart::compiler::target::word AOT_Thread_write_barrier_mask_offset = 40; static constexpr dart::compiler::target::word AOT_Thread_callback_code_offset = - 760; + 724; static constexpr dart::compiler::target::word AOT_TimelineStream_enabled_offset = 8; static constexpr dart::compiler::target::word AOT_TwoByteString_data_offset = @@ -4645,12 +4585,11 @@ static constexpr dart::compiler::target::word AOT_Code_entry_point_offset[] = { 4, 12, 8, 16}; static constexpr dart::compiler::target::word AOT_Thread_write_barrier_wrappers_thread_offset[] = { - 700, 704, 708, 712, 716, -1, 720, -1, 724, 728, -1, -1, -1, -1, -1, -1}; + 664, 668, 672, 676, 680, -1, 684, -1, 688, 692, -1, -1, -1, -1, -1, -1}; static constexpr dart::compiler::target::word AOT_ApiError_InstanceSize = 8; static constexpr dart::compiler::target::word AOT_Array_InstanceSize = 12; static constexpr dart::compiler::target::word AOT_Array_header_size = 12; static constexpr dart::compiler::target::word AOT_Bool_InstanceSize = 8; -static constexpr dart::compiler::target::word AOT_Bytecode_InstanceSize = 48; static constexpr dart::compiler::target::word AOT_Capability_InstanceSize = 16; static constexpr dart::compiler::target::word AOT_Class_InstanceSize = 112; static constexpr dart::compiler::target::word AOT_Closure_InstanceSize = 28; @@ -4692,7 +4631,7 @@ static constexpr dart::compiler::target::word static constexpr dart::compiler::target::word AOT_Int32x4_InstanceSize = 24; static constexpr dart::compiler::target::word AOT_Integer_InstanceSize = 4; static constexpr dart::compiler::target::word - AOT_KernelProgramInfo_InstanceSize = 64; + AOT_KernelProgramInfo_InstanceSize = 60; static constexpr dart::compiler::target::word AOT_LanguageError_InstanceSize = 28; static constexpr dart::compiler::target::word AOT_Library_InstanceSize = 80; @@ -4717,8 +4656,6 @@ static constexpr dart::compiler::target::word AOT_Object_InstanceSize = 4; static constexpr dart::compiler::target::word AOT_ObjectPool_InstanceSize = 8; static constexpr dart::compiler::target::word AOT_OneByteString_InstanceSize = 12; -static constexpr dart::compiler::target::word - AOT_ParameterTypeCheck_InstanceSize = 24; static constexpr dart::compiler::target::word AOT_PatchClass_InstanceSize = 20; static constexpr dart::compiler::target::word AOT_PcDescriptors_HeaderSize = 8; static constexpr dart::compiler::target::word AOT_Pointer_InstanceSize = 12; @@ -4984,153 +4921,149 @@ static constexpr dart::compiler::target::word AOT_String_length_offset = 8; static constexpr dart::compiler::target::word AOT_SubtypeTestCache_cache_offset = 8; static constexpr dart::compiler::target::word - AOT_Thread_AllocateArray_entry_point_offset = 752; + AOT_Thread_AllocateArray_entry_point_offset = 736; static constexpr dart::compiler::target::word - AOT_Thread_active_exception_offset = 1472; + AOT_Thread_active_exception_offset = 1400; static constexpr dart::compiler::target::word - AOT_Thread_active_stacktrace_offset = 1480; + AOT_Thread_active_stacktrace_offset = 1408; static constexpr dart::compiler::target::word AOT_Thread_array_write_barrier_code_offset = 240; static constexpr dart::compiler::target::word - AOT_Thread_array_write_barrier_entry_point_offset = 536; + AOT_Thread_array_write_barrier_entry_point_offset = 528; static constexpr dart::compiler::target::word - AOT_Thread_allocate_mint_with_fpu_regs_entry_point_offset = 552; + AOT_Thread_allocate_mint_with_fpu_regs_entry_point_offset = 544; static constexpr dart::compiler::target::word - AOT_Thread_allocate_mint_with_fpu_regs_stub_offset = 368; + AOT_Thread_allocate_mint_with_fpu_regs_stub_offset = 360; static constexpr dart::compiler::target::word - AOT_Thread_allocate_mint_without_fpu_regs_entry_point_offset = 560; + AOT_Thread_allocate_mint_without_fpu_regs_entry_point_offset = 552; static constexpr dart::compiler::target::word - AOT_Thread_allocate_mint_without_fpu_regs_stub_offset = 376; + AOT_Thread_allocate_mint_without_fpu_regs_stub_offset = 368; static constexpr dart::compiler::target::word - AOT_Thread_allocate_object_entry_point_offset = 568; + AOT_Thread_allocate_object_entry_point_offset = 560; static constexpr dart::compiler::target::word - AOT_Thread_allocate_object_stub_offset = 384; + AOT_Thread_allocate_object_stub_offset = 376; static constexpr dart::compiler::target::word - AOT_Thread_allocate_object_parameterized_entry_point_offset = 576; + AOT_Thread_allocate_object_parameterized_entry_point_offset = 568; static constexpr dart::compiler::target::word - AOT_Thread_allocate_object_parameterized_stub_offset = 392; + AOT_Thread_allocate_object_parameterized_stub_offset = 384; static constexpr dart::compiler::target::word - AOT_Thread_allocate_object_slow_entry_point_offset = 584; + AOT_Thread_allocate_object_slow_entry_point_offset = 576; static constexpr dart::compiler::target::word - AOT_Thread_allocate_object_slow_stub_offset = 400; + AOT_Thread_allocate_object_slow_stub_offset = 392; static constexpr dart::compiler::target::word AOT_Thread_api_top_scope_offset = - 1544; + 1472; static constexpr dart::compiler::target::word AOT_Thread_async_stack_trace_offset = 192; static constexpr dart::compiler::target::word - AOT_Thread_auto_scope_native_wrapper_entry_point_offset = 672; + AOT_Thread_auto_scope_native_wrapper_entry_point_offset = 664; static constexpr dart::compiler::target::word AOT_Thread_bool_false_offset = 224; static constexpr dart::compiler::target::word AOT_Thread_bool_true_offset = 216; static constexpr dart::compiler::target::word - AOT_Thread_bootstrap_native_wrapper_entry_point_offset = 656; + AOT_Thread_bootstrap_native_wrapper_entry_point_offset = 648; static constexpr dart::compiler::target::word - AOT_Thread_call_to_runtime_entry_point_offset = 544; + AOT_Thread_call_to_runtime_entry_point_offset = 536; static constexpr dart::compiler::target::word - AOT_Thread_call_to_runtime_stub_offset = 280; + AOT_Thread_call_to_runtime_stub_offset = 272; static constexpr dart::compiler::target::word AOT_Thread_dart_stream_offset = - 1560; + 1488; static constexpr dart::compiler::target::word AOT_Thread_dispatch_table_array_offset = 96; static constexpr dart::compiler::target::word AOT_Thread_optimize_entry_offset = - 624; + 616; static constexpr dart::compiler::target::word AOT_Thread_optimize_stub_offset = - 456; + 448; static constexpr dart::compiler::target::word - AOT_Thread_deoptimize_entry_offset = 632; + AOT_Thread_deoptimize_entry_offset = 624; static constexpr dart::compiler::target::word - AOT_Thread_deoptimize_stub_offset = 464; + AOT_Thread_deoptimize_stub_offset = 456; static constexpr dart::compiler::target::word - AOT_Thread_double_abs_address_offset = 712; + AOT_Thread_double_abs_address_offset = 696; static constexpr dart::compiler::target::word - AOT_Thread_double_negate_address_offset = 704; + AOT_Thread_double_negate_address_offset = 688; static constexpr dart::compiler::target::word AOT_Thread_end_offset = 112; static constexpr dart::compiler::target::word - AOT_Thread_enter_safepoint_stub_offset = 504; + AOT_Thread_enter_safepoint_stub_offset = 496; static constexpr dart::compiler::target::word - AOT_Thread_execution_state_offset = 1512; + AOT_Thread_execution_state_offset = 1440; static constexpr dart::compiler::target::word - AOT_Thread_exit_safepoint_stub_offset = 512; + AOT_Thread_exit_safepoint_stub_offset = 504; static constexpr dart::compiler::target::word - AOT_Thread_call_native_through_safepoint_stub_offset = 520; + AOT_Thread_call_native_through_safepoint_stub_offset = 512; static constexpr dart::compiler::target::word - AOT_Thread_call_native_through_safepoint_entry_point_offset = 640; + AOT_Thread_call_native_through_safepoint_entry_point_offset = 632; static constexpr dart::compiler::target::word AOT_Thread_fix_allocation_stub_code_offset = 256; static constexpr dart::compiler::target::word AOT_Thread_fix_callers_target_code_offset = 248; static constexpr dart::compiler::target::word - AOT_Thread_float_absolute_address_offset = 736; + AOT_Thread_float_absolute_address_offset = 720; static constexpr dart::compiler::target::word - AOT_Thread_float_negate_address_offset = 728; + AOT_Thread_float_negate_address_offset = 712; static constexpr dart::compiler::target::word - AOT_Thread_float_not_address_offset = 720; + AOT_Thread_float_not_address_offset = 704; static constexpr dart::compiler::target::word - AOT_Thread_float_zerow_address_offset = 744; + AOT_Thread_float_zerow_address_offset = 728; static constexpr dart::compiler::target::word - AOT_Thread_global_object_pool_offset = 1488; -static constexpr dart::compiler::target::word - AOT_Thread_interpret_call_entry_point_offset = 680; -static constexpr dart::compiler::target::word - AOT_Thread_invoke_dart_code_from_bytecode_stub_offset = 272; + AOT_Thread_global_object_pool_offset = 1416; static constexpr dart::compiler::target::word AOT_Thread_invoke_dart_code_stub_offset = 264; static constexpr dart::compiler::target::word - AOT_Thread_exit_through_ffi_offset = 1536; + AOT_Thread_exit_through_ffi_offset = 1464; static constexpr dart::compiler::target::word AOT_Thread_isolate_offset = 88; static constexpr dart::compiler::target::word AOT_Thread_field_table_values_offset = 136; static constexpr dart::compiler::target::word - AOT_Thread_lazy_deopt_from_return_stub_offset = 472; + AOT_Thread_lazy_deopt_from_return_stub_offset = 464; static constexpr dart::compiler::target::word - AOT_Thread_lazy_deopt_from_throw_stub_offset = 480; + AOT_Thread_lazy_deopt_from_throw_stub_offset = 472; static constexpr dart::compiler::target::word - AOT_Thread_lazy_specialize_type_test_stub_offset = 496; + AOT_Thread_lazy_specialize_type_test_stub_offset = 488; static constexpr dart::compiler::target::word AOT_Thread_marking_stack_block_offset = 168; static constexpr dart::compiler::target::word - AOT_Thread_megamorphic_call_checked_entry_offset = 608; + AOT_Thread_megamorphic_call_checked_entry_offset = 600; static constexpr dart::compiler::target::word - AOT_Thread_switchable_call_miss_entry_offset = 616; + AOT_Thread_switchable_call_miss_entry_offset = 608; static constexpr dart::compiler::target::word - AOT_Thread_switchable_call_miss_stub_offset = 424; + AOT_Thread_switchable_call_miss_stub_offset = 416; static constexpr dart::compiler::target::word - AOT_Thread_no_scope_native_wrapper_entry_point_offset = 664; + AOT_Thread_no_scope_native_wrapper_entry_point_offset = 656; static constexpr dart::compiler::target::word - AOT_Thread_late_initialization_error_shared_with_fpu_regs_stub_offset = 296; + AOT_Thread_late_initialization_error_shared_with_fpu_regs_stub_offset = 288; static constexpr dart::compiler::target::word AOT_Thread_late_initialization_error_shared_without_fpu_regs_stub_offset = - 288; + 280; static constexpr dart::compiler::target::word - AOT_Thread_null_error_shared_with_fpu_regs_stub_offset = 312; + AOT_Thread_null_error_shared_with_fpu_regs_stub_offset = 304; static constexpr dart::compiler::target::word - AOT_Thread_null_error_shared_without_fpu_regs_stub_offset = 304; + AOT_Thread_null_error_shared_without_fpu_regs_stub_offset = 296; static constexpr dart::compiler::target::word - AOT_Thread_null_arg_error_shared_with_fpu_regs_stub_offset = 328; + AOT_Thread_null_arg_error_shared_with_fpu_regs_stub_offset = 320; static constexpr dart::compiler::target::word - AOT_Thread_null_arg_error_shared_without_fpu_regs_stub_offset = 320; + AOT_Thread_null_arg_error_shared_without_fpu_regs_stub_offset = 312; static constexpr dart::compiler::target::word - AOT_Thread_null_cast_error_shared_with_fpu_regs_stub_offset = 344; + AOT_Thread_null_cast_error_shared_with_fpu_regs_stub_offset = 336; static constexpr dart::compiler::target::word - AOT_Thread_null_cast_error_shared_without_fpu_regs_stub_offset = 336; + AOT_Thread_null_cast_error_shared_without_fpu_regs_stub_offset = 328; static constexpr dart::compiler::target::word - AOT_Thread_range_error_shared_with_fpu_regs_stub_offset = 360; + AOT_Thread_range_error_shared_with_fpu_regs_stub_offset = 352; static constexpr dart::compiler::target::word - AOT_Thread_range_error_shared_without_fpu_regs_stub_offset = 352; + AOT_Thread_range_error_shared_without_fpu_regs_stub_offset = 344; static constexpr dart::compiler::target::word AOT_Thread_object_null_offset = 208; static constexpr dart::compiler::target::word - AOT_Thread_predefined_symbols_address_offset = 688; + AOT_Thread_predefined_symbols_address_offset = 672; static constexpr dart::compiler::target::word AOT_Thread_resume_pc_offset = - 1496; + 1424; static constexpr dart::compiler::target::word - AOT_Thread_saved_shadow_call_stack_offset = 1504; + AOT_Thread_saved_shadow_call_stack_offset = 1432; static constexpr dart::compiler::target::word - AOT_Thread_safepoint_state_offset = 1520; + AOT_Thread_safepoint_state_offset = 1448; static constexpr dart::compiler::target::word - AOT_Thread_slow_type_test_stub_offset = 488; + AOT_Thread_slow_type_test_stub_offset = 480; static constexpr dart::compiler::target::word - AOT_Thread_slow_type_test_entry_point_offset = 648; + AOT_Thread_slow_type_test_entry_point_offset = 640; static constexpr dart::compiler::target::word AOT_Thread_stack_limit_offset = 72; static constexpr dart::compiler::target::word @@ -5138,13 +5071,13 @@ static constexpr dart::compiler::target::word static constexpr dart::compiler::target::word AOT_Thread_stack_overflow_flags_offset = 128; static constexpr dart::compiler::target::word - AOT_Thread_stack_overflow_shared_with_fpu_regs_entry_point_offset = 600; + AOT_Thread_stack_overflow_shared_with_fpu_regs_entry_point_offset = 592; static constexpr dart::compiler::target::word - AOT_Thread_stack_overflow_shared_with_fpu_regs_stub_offset = 416; + AOT_Thread_stack_overflow_shared_with_fpu_regs_stub_offset = 408; static constexpr dart::compiler::target::word - AOT_Thread_stack_overflow_shared_without_fpu_regs_entry_point_offset = 592; + AOT_Thread_stack_overflow_shared_without_fpu_regs_entry_point_offset = 584; static constexpr dart::compiler::target::word - AOT_Thread_stack_overflow_shared_without_fpu_regs_stub_offset = 408; + AOT_Thread_stack_overflow_shared_without_fpu_regs_stub_offset = 400; static constexpr dart::compiler::target::word AOT_Thread_store_buffer_block_offset = 160; static constexpr dart::compiler::target::word @@ -5158,11 +5091,11 @@ static constexpr dart::compiler::target::word AOT_Thread_vm_tag_offset = 184; static constexpr dart::compiler::target::word AOT_Thread_write_barrier_code_offset = 232; static constexpr dart::compiler::target::word - AOT_Thread_write_barrier_entry_point_offset = 528; + AOT_Thread_write_barrier_entry_point_offset = 520; static constexpr dart::compiler::target::word AOT_Thread_write_barrier_mask_offset = 80; static constexpr dart::compiler::target::word AOT_Thread_callback_code_offset = - 1528; + 1456; static constexpr dart::compiler::target::word AOT_TimelineStream_enabled_offset = 16; static constexpr dart::compiler::target::word AOT_TwoByteString_data_offset = @@ -5225,13 +5158,12 @@ static constexpr dart::compiler::target::word AOT_Code_entry_point_offset[] = { 8, 24, 16, 32}; static constexpr dart::compiler::target::word AOT_Thread_write_barrier_wrappers_thread_offset[] = { - 1384, 1392, 1400, 1408, -1, -1, 1416, 1424, - 1432, 1440, 1448, -1, 1456, 1464, -1, -1}; + 1312, 1320, 1328, 1336, -1, -1, 1344, 1352, + 1360, 1368, 1376, -1, 1384, 1392, -1, -1}; static constexpr dart::compiler::target::word AOT_ApiError_InstanceSize = 16; static constexpr dart::compiler::target::word AOT_Array_InstanceSize = 24; static constexpr dart::compiler::target::word AOT_Array_header_size = 24; static constexpr dart::compiler::target::word AOT_Bool_InstanceSize = 12; -static constexpr dart::compiler::target::word AOT_Bytecode_InstanceSize = 88; static constexpr dart::compiler::target::word AOT_Capability_InstanceSize = 16; static constexpr dart::compiler::target::word AOT_Class_InstanceSize = 192; static constexpr dart::compiler::target::word AOT_Closure_InstanceSize = 56; @@ -5273,7 +5205,7 @@ static constexpr dart::compiler::target::word static constexpr dart::compiler::target::word AOT_Int32x4_InstanceSize = 24; static constexpr dart::compiler::target::word AOT_Integer_InstanceSize = 8; static constexpr dart::compiler::target::word - AOT_KernelProgramInfo_InstanceSize = 128; + AOT_KernelProgramInfo_InstanceSize = 120; static constexpr dart::compiler::target::word AOT_LanguageError_InstanceSize = 48; static constexpr dart::compiler::target::word AOT_Library_InstanceSize = 152; @@ -5298,8 +5230,6 @@ static constexpr dart::compiler::target::word AOT_Object_InstanceSize = 8; static constexpr dart::compiler::target::word AOT_ObjectPool_InstanceSize = 16; static constexpr dart::compiler::target::word AOT_OneByteString_InstanceSize = 16; -static constexpr dart::compiler::target::word - AOT_ParameterTypeCheck_InstanceSize = 48; static constexpr dart::compiler::target::word AOT_PatchClass_InstanceSize = 40; static constexpr dart::compiler::target::word AOT_PcDescriptors_HeaderSize = 16; static constexpr dart::compiler::target::word AOT_Pointer_InstanceSize = 24; @@ -5568,153 +5498,149 @@ static constexpr dart::compiler::target::word AOT_String_length_offset = 8; static constexpr dart::compiler::target::word AOT_SubtypeTestCache_cache_offset = 8; static constexpr dart::compiler::target::word - AOT_Thread_AllocateArray_entry_point_offset = 752; + AOT_Thread_AllocateArray_entry_point_offset = 736; static constexpr dart::compiler::target::word - AOT_Thread_active_exception_offset = 1544; + AOT_Thread_active_exception_offset = 1472; static constexpr dart::compiler::target::word - AOT_Thread_active_stacktrace_offset = 1552; + AOT_Thread_active_stacktrace_offset = 1480; static constexpr dart::compiler::target::word AOT_Thread_array_write_barrier_code_offset = 240; static constexpr dart::compiler::target::word - AOT_Thread_array_write_barrier_entry_point_offset = 536; + AOT_Thread_array_write_barrier_entry_point_offset = 528; static constexpr dart::compiler::target::word - AOT_Thread_allocate_mint_with_fpu_regs_entry_point_offset = 552; + AOT_Thread_allocate_mint_with_fpu_regs_entry_point_offset = 544; static constexpr dart::compiler::target::word - AOT_Thread_allocate_mint_with_fpu_regs_stub_offset = 368; + AOT_Thread_allocate_mint_with_fpu_regs_stub_offset = 360; static constexpr dart::compiler::target::word - AOT_Thread_allocate_mint_without_fpu_regs_entry_point_offset = 560; + AOT_Thread_allocate_mint_without_fpu_regs_entry_point_offset = 552; static constexpr dart::compiler::target::word - AOT_Thread_allocate_mint_without_fpu_regs_stub_offset = 376; + AOT_Thread_allocate_mint_without_fpu_regs_stub_offset = 368; static constexpr dart::compiler::target::word - AOT_Thread_allocate_object_entry_point_offset = 568; + AOT_Thread_allocate_object_entry_point_offset = 560; static constexpr dart::compiler::target::word - AOT_Thread_allocate_object_stub_offset = 384; + AOT_Thread_allocate_object_stub_offset = 376; static constexpr dart::compiler::target::word - AOT_Thread_allocate_object_parameterized_entry_point_offset = 576; + AOT_Thread_allocate_object_parameterized_entry_point_offset = 568; static constexpr dart::compiler::target::word - AOT_Thread_allocate_object_parameterized_stub_offset = 392; + AOT_Thread_allocate_object_parameterized_stub_offset = 384; static constexpr dart::compiler::target::word - AOT_Thread_allocate_object_slow_entry_point_offset = 584; + AOT_Thread_allocate_object_slow_entry_point_offset = 576; static constexpr dart::compiler::target::word - AOT_Thread_allocate_object_slow_stub_offset = 400; + AOT_Thread_allocate_object_slow_stub_offset = 392; static constexpr dart::compiler::target::word AOT_Thread_api_top_scope_offset = - 1616; + 1544; static constexpr dart::compiler::target::word AOT_Thread_async_stack_trace_offset = 192; static constexpr dart::compiler::target::word - AOT_Thread_auto_scope_native_wrapper_entry_point_offset = 672; + AOT_Thread_auto_scope_native_wrapper_entry_point_offset = 664; static constexpr dart::compiler::target::word AOT_Thread_bool_false_offset = 224; static constexpr dart::compiler::target::word AOT_Thread_bool_true_offset = 216; static constexpr dart::compiler::target::word - AOT_Thread_bootstrap_native_wrapper_entry_point_offset = 656; + AOT_Thread_bootstrap_native_wrapper_entry_point_offset = 648; static constexpr dart::compiler::target::word - AOT_Thread_call_to_runtime_entry_point_offset = 544; + AOT_Thread_call_to_runtime_entry_point_offset = 536; static constexpr dart::compiler::target::word - AOT_Thread_call_to_runtime_stub_offset = 280; + AOT_Thread_call_to_runtime_stub_offset = 272; static constexpr dart::compiler::target::word AOT_Thread_dart_stream_offset = - 1632; + 1560; static constexpr dart::compiler::target::word AOT_Thread_dispatch_table_array_offset = 96; static constexpr dart::compiler::target::word AOT_Thread_optimize_entry_offset = - 624; + 616; static constexpr dart::compiler::target::word AOT_Thread_optimize_stub_offset = - 456; + 448; static constexpr dart::compiler::target::word - AOT_Thread_deoptimize_entry_offset = 632; + AOT_Thread_deoptimize_entry_offset = 624; static constexpr dart::compiler::target::word - AOT_Thread_deoptimize_stub_offset = 464; + AOT_Thread_deoptimize_stub_offset = 456; static constexpr dart::compiler::target::word - AOT_Thread_double_abs_address_offset = 712; + AOT_Thread_double_abs_address_offset = 696; static constexpr dart::compiler::target::word - AOT_Thread_double_negate_address_offset = 704; + AOT_Thread_double_negate_address_offset = 688; static constexpr dart::compiler::target::word AOT_Thread_end_offset = 112; static constexpr dart::compiler::target::word - AOT_Thread_enter_safepoint_stub_offset = 504; + AOT_Thread_enter_safepoint_stub_offset = 496; static constexpr dart::compiler::target::word - AOT_Thread_execution_state_offset = 1584; + AOT_Thread_execution_state_offset = 1512; static constexpr dart::compiler::target::word - AOT_Thread_exit_safepoint_stub_offset = 512; + AOT_Thread_exit_safepoint_stub_offset = 504; static constexpr dart::compiler::target::word - AOT_Thread_call_native_through_safepoint_stub_offset = 520; + AOT_Thread_call_native_through_safepoint_stub_offset = 512; static constexpr dart::compiler::target::word - AOT_Thread_call_native_through_safepoint_entry_point_offset = 640; + AOT_Thread_call_native_through_safepoint_entry_point_offset = 632; static constexpr dart::compiler::target::word AOT_Thread_fix_allocation_stub_code_offset = 256; static constexpr dart::compiler::target::word AOT_Thread_fix_callers_target_code_offset = 248; static constexpr dart::compiler::target::word - AOT_Thread_float_absolute_address_offset = 736; + AOT_Thread_float_absolute_address_offset = 720; static constexpr dart::compiler::target::word - AOT_Thread_float_negate_address_offset = 728; + AOT_Thread_float_negate_address_offset = 712; static constexpr dart::compiler::target::word - AOT_Thread_float_not_address_offset = 720; + AOT_Thread_float_not_address_offset = 704; static constexpr dart::compiler::target::word - AOT_Thread_float_zerow_address_offset = 744; + AOT_Thread_float_zerow_address_offset = 728; static constexpr dart::compiler::target::word - AOT_Thread_global_object_pool_offset = 1560; -static constexpr dart::compiler::target::word - AOT_Thread_interpret_call_entry_point_offset = 680; -static constexpr dart::compiler::target::word - AOT_Thread_invoke_dart_code_from_bytecode_stub_offset = 272; + AOT_Thread_global_object_pool_offset = 1488; static constexpr dart::compiler::target::word AOT_Thread_invoke_dart_code_stub_offset = 264; static constexpr dart::compiler::target::word - AOT_Thread_exit_through_ffi_offset = 1608; + AOT_Thread_exit_through_ffi_offset = 1536; static constexpr dart::compiler::target::word AOT_Thread_isolate_offset = 88; static constexpr dart::compiler::target::word AOT_Thread_field_table_values_offset = 136; static constexpr dart::compiler::target::word - AOT_Thread_lazy_deopt_from_return_stub_offset = 472; + AOT_Thread_lazy_deopt_from_return_stub_offset = 464; static constexpr dart::compiler::target::word - AOT_Thread_lazy_deopt_from_throw_stub_offset = 480; + AOT_Thread_lazy_deopt_from_throw_stub_offset = 472; static constexpr dart::compiler::target::word - AOT_Thread_lazy_specialize_type_test_stub_offset = 496; + AOT_Thread_lazy_specialize_type_test_stub_offset = 488; static constexpr dart::compiler::target::word AOT_Thread_marking_stack_block_offset = 168; static constexpr dart::compiler::target::word - AOT_Thread_megamorphic_call_checked_entry_offset = 608; + AOT_Thread_megamorphic_call_checked_entry_offset = 600; static constexpr dart::compiler::target::word - AOT_Thread_switchable_call_miss_entry_offset = 616; + AOT_Thread_switchable_call_miss_entry_offset = 608; static constexpr dart::compiler::target::word - AOT_Thread_switchable_call_miss_stub_offset = 424; + AOT_Thread_switchable_call_miss_stub_offset = 416; static constexpr dart::compiler::target::word - AOT_Thread_no_scope_native_wrapper_entry_point_offset = 664; + AOT_Thread_no_scope_native_wrapper_entry_point_offset = 656; static constexpr dart::compiler::target::word - AOT_Thread_late_initialization_error_shared_with_fpu_regs_stub_offset = 296; + AOT_Thread_late_initialization_error_shared_with_fpu_regs_stub_offset = 288; static constexpr dart::compiler::target::word AOT_Thread_late_initialization_error_shared_without_fpu_regs_stub_offset = - 288; + 280; static constexpr dart::compiler::target::word - AOT_Thread_null_error_shared_with_fpu_regs_stub_offset = 312; + AOT_Thread_null_error_shared_with_fpu_regs_stub_offset = 304; static constexpr dart::compiler::target::word - AOT_Thread_null_error_shared_without_fpu_regs_stub_offset = 304; + AOT_Thread_null_error_shared_without_fpu_regs_stub_offset = 296; static constexpr dart::compiler::target::word - AOT_Thread_null_arg_error_shared_with_fpu_regs_stub_offset = 328; + AOT_Thread_null_arg_error_shared_with_fpu_regs_stub_offset = 320; static constexpr dart::compiler::target::word - AOT_Thread_null_arg_error_shared_without_fpu_regs_stub_offset = 320; + AOT_Thread_null_arg_error_shared_without_fpu_regs_stub_offset = 312; static constexpr dart::compiler::target::word - AOT_Thread_null_cast_error_shared_with_fpu_regs_stub_offset = 344; + AOT_Thread_null_cast_error_shared_with_fpu_regs_stub_offset = 336; static constexpr dart::compiler::target::word - AOT_Thread_null_cast_error_shared_without_fpu_regs_stub_offset = 336; + AOT_Thread_null_cast_error_shared_without_fpu_regs_stub_offset = 328; static constexpr dart::compiler::target::word - AOT_Thread_range_error_shared_with_fpu_regs_stub_offset = 360; + AOT_Thread_range_error_shared_with_fpu_regs_stub_offset = 352; static constexpr dart::compiler::target::word - AOT_Thread_range_error_shared_without_fpu_regs_stub_offset = 352; + AOT_Thread_range_error_shared_without_fpu_regs_stub_offset = 344; static constexpr dart::compiler::target::word AOT_Thread_object_null_offset = 208; static constexpr dart::compiler::target::word - AOT_Thread_predefined_symbols_address_offset = 688; + AOT_Thread_predefined_symbols_address_offset = 672; static constexpr dart::compiler::target::word AOT_Thread_resume_pc_offset = - 1568; + 1496; static constexpr dart::compiler::target::word - AOT_Thread_saved_shadow_call_stack_offset = 1576; + AOT_Thread_saved_shadow_call_stack_offset = 1504; static constexpr dart::compiler::target::word - AOT_Thread_safepoint_state_offset = 1592; + AOT_Thread_safepoint_state_offset = 1520; static constexpr dart::compiler::target::word - AOT_Thread_slow_type_test_stub_offset = 488; + AOT_Thread_slow_type_test_stub_offset = 480; static constexpr dart::compiler::target::word - AOT_Thread_slow_type_test_entry_point_offset = 648; + AOT_Thread_slow_type_test_entry_point_offset = 640; static constexpr dart::compiler::target::word AOT_Thread_stack_limit_offset = 72; static constexpr dart::compiler::target::word @@ -5722,13 +5648,13 @@ static constexpr dart::compiler::target::word static constexpr dart::compiler::target::word AOT_Thread_stack_overflow_flags_offset = 128; static constexpr dart::compiler::target::word - AOT_Thread_stack_overflow_shared_with_fpu_regs_entry_point_offset = 600; + AOT_Thread_stack_overflow_shared_with_fpu_regs_entry_point_offset = 592; static constexpr dart::compiler::target::word - AOT_Thread_stack_overflow_shared_with_fpu_regs_stub_offset = 416; + AOT_Thread_stack_overflow_shared_with_fpu_regs_stub_offset = 408; static constexpr dart::compiler::target::word - AOT_Thread_stack_overflow_shared_without_fpu_regs_entry_point_offset = 592; + AOT_Thread_stack_overflow_shared_without_fpu_regs_entry_point_offset = 584; static constexpr dart::compiler::target::word - AOT_Thread_stack_overflow_shared_without_fpu_regs_stub_offset = 408; + AOT_Thread_stack_overflow_shared_without_fpu_regs_stub_offset = 400; static constexpr dart::compiler::target::word AOT_Thread_store_buffer_block_offset = 160; static constexpr dart::compiler::target::word @@ -5742,11 +5668,11 @@ static constexpr dart::compiler::target::word AOT_Thread_vm_tag_offset = 184; static constexpr dart::compiler::target::word AOT_Thread_write_barrier_code_offset = 232; static constexpr dart::compiler::target::word - AOT_Thread_write_barrier_entry_point_offset = 528; + AOT_Thread_write_barrier_entry_point_offset = 520; static constexpr dart::compiler::target::word AOT_Thread_write_barrier_mask_offset = 80; static constexpr dart::compiler::target::word AOT_Thread_callback_code_offset = - 1600; + 1528; static constexpr dart::compiler::target::word AOT_TimelineStream_enabled_offset = 16; static constexpr dart::compiler::target::word AOT_TwoByteString_data_offset = @@ -5809,14 +5735,13 @@ static constexpr dart::compiler::target::word AOT_Code_entry_point_offset[] = { 8, 24, 16, 32}; static constexpr dart::compiler::target::word AOT_Thread_write_barrier_wrappers_thread_offset[] = { - 1384, 1392, 1400, 1408, 1416, 1424, 1432, 1440, 1448, 1456, 1464, - 1472, 1480, 1488, 1496, -1, -1, -1, -1, 1504, 1512, -1, - -1, 1520, 1528, 1536, -1, -1, -1, -1, -1, -1}; + 1312, 1320, 1328, 1336, 1344, 1352, 1360, 1368, 1376, 1384, 1392, + 1400, 1408, 1416, 1424, -1, -1, -1, -1, 1432, 1440, -1, + -1, 1448, 1456, 1464, -1, -1, -1, -1, -1, -1}; static constexpr dart::compiler::target::word AOT_ApiError_InstanceSize = 16; static constexpr dart::compiler::target::word AOT_Array_InstanceSize = 24; static constexpr dart::compiler::target::word AOT_Array_header_size = 24; static constexpr dart::compiler::target::word AOT_Bool_InstanceSize = 12; -static constexpr dart::compiler::target::word AOT_Bytecode_InstanceSize = 88; static constexpr dart::compiler::target::word AOT_Capability_InstanceSize = 16; static constexpr dart::compiler::target::word AOT_Class_InstanceSize = 192; static constexpr dart::compiler::target::word AOT_Closure_InstanceSize = 56; @@ -5858,7 +5783,7 @@ static constexpr dart::compiler::target::word static constexpr dart::compiler::target::word AOT_Int32x4_InstanceSize = 24; static constexpr dart::compiler::target::word AOT_Integer_InstanceSize = 8; static constexpr dart::compiler::target::word - AOT_KernelProgramInfo_InstanceSize = 128; + AOT_KernelProgramInfo_InstanceSize = 120; static constexpr dart::compiler::target::word AOT_LanguageError_InstanceSize = 48; static constexpr dart::compiler::target::word AOT_Library_InstanceSize = 152; @@ -5883,8 +5808,6 @@ static constexpr dart::compiler::target::word AOT_Object_InstanceSize = 8; static constexpr dart::compiler::target::word AOT_ObjectPool_InstanceSize = 16; static constexpr dart::compiler::target::word AOT_OneByteString_InstanceSize = 16; -static constexpr dart::compiler::target::word - AOT_ParameterTypeCheck_InstanceSize = 48; static constexpr dart::compiler::target::word AOT_PatchClass_InstanceSize = 40; static constexpr dart::compiler::target::word AOT_PcDescriptors_HeaderSize = 16; static constexpr dart::compiler::target::word AOT_Pointer_InstanceSize = 24; @@ -6147,152 +6070,148 @@ static constexpr dart::compiler::target::word AOT_String_length_offset = 4; static constexpr dart::compiler::target::word AOT_SubtypeTestCache_cache_offset = 4; static constexpr dart::compiler::target::word - AOT_Thread_AllocateArray_entry_point_offset = 384; + AOT_Thread_AllocateArray_entry_point_offset = 376; static constexpr dart::compiler::target::word - AOT_Thread_active_exception_offset = 732; + AOT_Thread_active_exception_offset = 696; static constexpr dart::compiler::target::word - AOT_Thread_active_stacktrace_offset = 736; + AOT_Thread_active_stacktrace_offset = 700; static constexpr dart::compiler::target::word AOT_Thread_array_write_barrier_code_offset = 128; static constexpr dart::compiler::target::word - AOT_Thread_array_write_barrier_entry_point_offset = 276; + AOT_Thread_array_write_barrier_entry_point_offset = 272; static constexpr dart::compiler::target::word - AOT_Thread_allocate_mint_with_fpu_regs_entry_point_offset = 284; + AOT_Thread_allocate_mint_with_fpu_regs_entry_point_offset = 280; static constexpr dart::compiler::target::word - AOT_Thread_allocate_mint_with_fpu_regs_stub_offset = 192; + AOT_Thread_allocate_mint_with_fpu_regs_stub_offset = 188; static constexpr dart::compiler::target::word - AOT_Thread_allocate_mint_without_fpu_regs_entry_point_offset = 288; + AOT_Thread_allocate_mint_without_fpu_regs_entry_point_offset = 284; static constexpr dart::compiler::target::word - AOT_Thread_allocate_mint_without_fpu_regs_stub_offset = 196; + AOT_Thread_allocate_mint_without_fpu_regs_stub_offset = 192; static constexpr dart::compiler::target::word - AOT_Thread_allocate_object_entry_point_offset = 292; + AOT_Thread_allocate_object_entry_point_offset = 288; static constexpr dart::compiler::target::word - AOT_Thread_allocate_object_stub_offset = 200; + AOT_Thread_allocate_object_stub_offset = 196; static constexpr dart::compiler::target::word - AOT_Thread_allocate_object_parameterized_entry_point_offset = 296; + AOT_Thread_allocate_object_parameterized_entry_point_offset = 292; static constexpr dart::compiler::target::word - AOT_Thread_allocate_object_parameterized_stub_offset = 204; + AOT_Thread_allocate_object_parameterized_stub_offset = 200; static constexpr dart::compiler::target::word - AOT_Thread_allocate_object_slow_entry_point_offset = 300; + AOT_Thread_allocate_object_slow_entry_point_offset = 296; static constexpr dart::compiler::target::word - AOT_Thread_allocate_object_slow_stub_offset = 208; + AOT_Thread_allocate_object_slow_stub_offset = 204; static constexpr dart::compiler::target::word AOT_Thread_api_top_scope_offset = - 768; + 732; static constexpr dart::compiler::target::word AOT_Thread_async_stack_trace_offset = 96; static constexpr dart::compiler::target::word - AOT_Thread_auto_scope_native_wrapper_entry_point_offset = 344; + AOT_Thread_auto_scope_native_wrapper_entry_point_offset = 340; static constexpr dart::compiler::target::word AOT_Thread_bool_false_offset = 120; static constexpr dart::compiler::target::word AOT_Thread_bool_true_offset = 116; static constexpr dart::compiler::target::word - AOT_Thread_bootstrap_native_wrapper_entry_point_offset = 336; + AOT_Thread_bootstrap_native_wrapper_entry_point_offset = 332; static constexpr dart::compiler::target::word - AOT_Thread_call_to_runtime_entry_point_offset = 280; + AOT_Thread_call_to_runtime_entry_point_offset = 276; static constexpr dart::compiler::target::word - AOT_Thread_call_to_runtime_stub_offset = 148; + AOT_Thread_call_to_runtime_stub_offset = 144; static constexpr dart::compiler::target::word AOT_Thread_dart_stream_offset = - 776; + 740; static constexpr dart::compiler::target::word AOT_Thread_dispatch_table_array_offset = 48; static constexpr dart::compiler::target::word AOT_Thread_optimize_entry_offset = - 320; + 316; static constexpr dart::compiler::target::word AOT_Thread_optimize_stub_offset = - 236; + 232; static constexpr dart::compiler::target::word - AOT_Thread_deoptimize_entry_offset = 324; + AOT_Thread_deoptimize_entry_offset = 320; static constexpr dart::compiler::target::word - AOT_Thread_deoptimize_stub_offset = 240; + AOT_Thread_deoptimize_stub_offset = 236; static constexpr dart::compiler::target::word - AOT_Thread_double_abs_address_offset = 364; + AOT_Thread_double_abs_address_offset = 356; static constexpr dart::compiler::target::word - AOT_Thread_double_negate_address_offset = 360; + AOT_Thread_double_negate_address_offset = 352; static constexpr dart::compiler::target::word AOT_Thread_end_offset = 56; static constexpr dart::compiler::target::word - AOT_Thread_enter_safepoint_stub_offset = 260; + AOT_Thread_enter_safepoint_stub_offset = 256; static constexpr dart::compiler::target::word - AOT_Thread_execution_state_offset = 752; + AOT_Thread_execution_state_offset = 716; static constexpr dart::compiler::target::word - AOT_Thread_exit_safepoint_stub_offset = 264; + AOT_Thread_exit_safepoint_stub_offset = 260; static constexpr dart::compiler::target::word - AOT_Thread_call_native_through_safepoint_stub_offset = 268; + AOT_Thread_call_native_through_safepoint_stub_offset = 264; static constexpr dart::compiler::target::word - AOT_Thread_call_native_through_safepoint_entry_point_offset = 328; + AOT_Thread_call_native_through_safepoint_entry_point_offset = 324; static constexpr dart::compiler::target::word AOT_Thread_fix_allocation_stub_code_offset = 136; static constexpr dart::compiler::target::word AOT_Thread_fix_callers_target_code_offset = 132; static constexpr dart::compiler::target::word - AOT_Thread_float_absolute_address_offset = 376; + AOT_Thread_float_absolute_address_offset = 368; static constexpr dart::compiler::target::word - AOT_Thread_float_negate_address_offset = 372; + AOT_Thread_float_negate_address_offset = 364; static constexpr dart::compiler::target::word - AOT_Thread_float_not_address_offset = 368; + AOT_Thread_float_not_address_offset = 360; static constexpr dart::compiler::target::word - AOT_Thread_float_zerow_address_offset = 380; + AOT_Thread_float_zerow_address_offset = 372; static constexpr dart::compiler::target::word - AOT_Thread_global_object_pool_offset = 740; -static constexpr dart::compiler::target::word - AOT_Thread_interpret_call_entry_point_offset = 348; -static constexpr dart::compiler::target::word - AOT_Thread_invoke_dart_code_from_bytecode_stub_offset = 144; + AOT_Thread_global_object_pool_offset = 704; static constexpr dart::compiler::target::word AOT_Thread_invoke_dart_code_stub_offset = 140; static constexpr dart::compiler::target::word - AOT_Thread_exit_through_ffi_offset = 764; + AOT_Thread_exit_through_ffi_offset = 728; static constexpr dart::compiler::target::word AOT_Thread_isolate_offset = 44; static constexpr dart::compiler::target::word AOT_Thread_field_table_values_offset = 68; static constexpr dart::compiler::target::word - AOT_Thread_lazy_deopt_from_return_stub_offset = 244; + AOT_Thread_lazy_deopt_from_return_stub_offset = 240; static constexpr dart::compiler::target::word - AOT_Thread_lazy_deopt_from_throw_stub_offset = 248; + AOT_Thread_lazy_deopt_from_throw_stub_offset = 244; static constexpr dart::compiler::target::word - AOT_Thread_lazy_specialize_type_test_stub_offset = 256; + AOT_Thread_lazy_specialize_type_test_stub_offset = 252; static constexpr dart::compiler::target::word AOT_Thread_marking_stack_block_offset = 84; static constexpr dart::compiler::target::word - AOT_Thread_megamorphic_call_checked_entry_offset = 312; + AOT_Thread_megamorphic_call_checked_entry_offset = 308; static constexpr dart::compiler::target::word - AOT_Thread_switchable_call_miss_entry_offset = 316; + AOT_Thread_switchable_call_miss_entry_offset = 312; static constexpr dart::compiler::target::word - AOT_Thread_switchable_call_miss_stub_offset = 220; + AOT_Thread_switchable_call_miss_stub_offset = 216; static constexpr dart::compiler::target::word - AOT_Thread_no_scope_native_wrapper_entry_point_offset = 340; + AOT_Thread_no_scope_native_wrapper_entry_point_offset = 336; static constexpr dart::compiler::target::word - AOT_Thread_late_initialization_error_shared_with_fpu_regs_stub_offset = 156; + AOT_Thread_late_initialization_error_shared_with_fpu_regs_stub_offset = 152; static constexpr dart::compiler::target::word AOT_Thread_late_initialization_error_shared_without_fpu_regs_stub_offset = - 152; + 148; static constexpr dart::compiler::target::word - AOT_Thread_null_error_shared_with_fpu_regs_stub_offset = 164; + AOT_Thread_null_error_shared_with_fpu_regs_stub_offset = 160; static constexpr dart::compiler::target::word - AOT_Thread_null_error_shared_without_fpu_regs_stub_offset = 160; + AOT_Thread_null_error_shared_without_fpu_regs_stub_offset = 156; static constexpr dart::compiler::target::word - AOT_Thread_null_arg_error_shared_with_fpu_regs_stub_offset = 172; + AOT_Thread_null_arg_error_shared_with_fpu_regs_stub_offset = 168; static constexpr dart::compiler::target::word - AOT_Thread_null_arg_error_shared_without_fpu_regs_stub_offset = 168; + AOT_Thread_null_arg_error_shared_without_fpu_regs_stub_offset = 164; static constexpr dart::compiler::target::word - AOT_Thread_null_cast_error_shared_with_fpu_regs_stub_offset = 180; + AOT_Thread_null_cast_error_shared_with_fpu_regs_stub_offset = 176; static constexpr dart::compiler::target::word - AOT_Thread_null_cast_error_shared_without_fpu_regs_stub_offset = 176; + AOT_Thread_null_cast_error_shared_without_fpu_regs_stub_offset = 172; static constexpr dart::compiler::target::word - AOT_Thread_range_error_shared_with_fpu_regs_stub_offset = 188; + AOT_Thread_range_error_shared_with_fpu_regs_stub_offset = 184; static constexpr dart::compiler::target::word - AOT_Thread_range_error_shared_without_fpu_regs_stub_offset = 184; + AOT_Thread_range_error_shared_without_fpu_regs_stub_offset = 180; static constexpr dart::compiler::target::word AOT_Thread_object_null_offset = 112; static constexpr dart::compiler::target::word - AOT_Thread_predefined_symbols_address_offset = 352; -static constexpr dart::compiler::target::word AOT_Thread_resume_pc_offset = 744; + AOT_Thread_predefined_symbols_address_offset = 344; +static constexpr dart::compiler::target::word AOT_Thread_resume_pc_offset = 708; static constexpr dart::compiler::target::word - AOT_Thread_saved_shadow_call_stack_offset = 748; + AOT_Thread_saved_shadow_call_stack_offset = 712; static constexpr dart::compiler::target::word - AOT_Thread_safepoint_state_offset = 756; + AOT_Thread_safepoint_state_offset = 720; static constexpr dart::compiler::target::word - AOT_Thread_slow_type_test_stub_offset = 252; + AOT_Thread_slow_type_test_stub_offset = 248; static constexpr dart::compiler::target::word - AOT_Thread_slow_type_test_entry_point_offset = 332; + AOT_Thread_slow_type_test_entry_point_offset = 328; static constexpr dart::compiler::target::word AOT_Thread_stack_limit_offset = 36; static constexpr dart::compiler::target::word @@ -6300,13 +6219,13 @@ static constexpr dart::compiler::target::word static constexpr dart::compiler::target::word AOT_Thread_stack_overflow_flags_offset = 64; static constexpr dart::compiler::target::word - AOT_Thread_stack_overflow_shared_with_fpu_regs_entry_point_offset = 308; + AOT_Thread_stack_overflow_shared_with_fpu_regs_entry_point_offset = 304; static constexpr dart::compiler::target::word - AOT_Thread_stack_overflow_shared_with_fpu_regs_stub_offset = 216; + AOT_Thread_stack_overflow_shared_with_fpu_regs_stub_offset = 212; static constexpr dart::compiler::target::word - AOT_Thread_stack_overflow_shared_without_fpu_regs_entry_point_offset = 304; + AOT_Thread_stack_overflow_shared_without_fpu_regs_entry_point_offset = 300; static constexpr dart::compiler::target::word - AOT_Thread_stack_overflow_shared_without_fpu_regs_stub_offset = 212; + AOT_Thread_stack_overflow_shared_without_fpu_regs_stub_offset = 208; static constexpr dart::compiler::target::word AOT_Thread_store_buffer_block_offset = 80; static constexpr dart::compiler::target::word @@ -6320,11 +6239,11 @@ static constexpr dart::compiler::target::word AOT_Thread_vm_tag_offset = 92; static constexpr dart::compiler::target::word AOT_Thread_write_barrier_code_offset = 124; static constexpr dart::compiler::target::word - AOT_Thread_write_barrier_entry_point_offset = 272; + AOT_Thread_write_barrier_entry_point_offset = 268; static constexpr dart::compiler::target::word AOT_Thread_write_barrier_mask_offset = 40; static constexpr dart::compiler::target::word AOT_Thread_callback_code_offset = - 760; + 724; static constexpr dart::compiler::target::word AOT_TimelineStream_enabled_offset = 8; static constexpr dart::compiler::target::word AOT_TwoByteString_data_offset = @@ -6384,12 +6303,11 @@ static constexpr dart::compiler::target::word AOT_Code_entry_point_offset[] = { 4, 12, 8, 16}; static constexpr dart::compiler::target::word AOT_Thread_write_barrier_wrappers_thread_offset[] = { - 700, 704, 708, 712, 716, -1, 720, -1, 724, 728, -1, -1, -1, -1, -1, -1}; + 664, 668, 672, 676, 680, -1, 684, -1, 688, 692, -1, -1, -1, -1, -1, -1}; static constexpr dart::compiler::target::word AOT_ApiError_InstanceSize = 8; static constexpr dart::compiler::target::word AOT_Array_InstanceSize = 12; static constexpr dart::compiler::target::word AOT_Array_header_size = 12; static constexpr dart::compiler::target::word AOT_Bool_InstanceSize = 8; -static constexpr dart::compiler::target::word AOT_Bytecode_InstanceSize = 44; static constexpr dart::compiler::target::word AOT_Capability_InstanceSize = 16; static constexpr dart::compiler::target::word AOT_Class_InstanceSize = 112; static constexpr dart::compiler::target::word AOT_Closure_InstanceSize = 28; @@ -6431,7 +6349,7 @@ static constexpr dart::compiler::target::word static constexpr dart::compiler::target::word AOT_Int32x4_InstanceSize = 24; static constexpr dart::compiler::target::word AOT_Integer_InstanceSize = 4; static constexpr dart::compiler::target::word - AOT_KernelProgramInfo_InstanceSize = 64; + AOT_KernelProgramInfo_InstanceSize = 60; static constexpr dart::compiler::target::word AOT_LanguageError_InstanceSize = 28; static constexpr dart::compiler::target::word AOT_Library_InstanceSize = 80; @@ -6456,8 +6374,6 @@ static constexpr dart::compiler::target::word AOT_Object_InstanceSize = 4; static constexpr dart::compiler::target::word AOT_ObjectPool_InstanceSize = 8; static constexpr dart::compiler::target::word AOT_OneByteString_InstanceSize = 12; -static constexpr dart::compiler::target::word - AOT_ParameterTypeCheck_InstanceSize = 24; static constexpr dart::compiler::target::word AOT_PatchClass_InstanceSize = 20; static constexpr dart::compiler::target::word AOT_PcDescriptors_HeaderSize = 8; static constexpr dart::compiler::target::word AOT_Pointer_InstanceSize = 12; @@ -6719,153 +6635,149 @@ static constexpr dart::compiler::target::word AOT_String_length_offset = 8; static constexpr dart::compiler::target::word AOT_SubtypeTestCache_cache_offset = 8; static constexpr dart::compiler::target::word - AOT_Thread_AllocateArray_entry_point_offset = 752; + AOT_Thread_AllocateArray_entry_point_offset = 736; static constexpr dart::compiler::target::word - AOT_Thread_active_exception_offset = 1472; + AOT_Thread_active_exception_offset = 1400; static constexpr dart::compiler::target::word - AOT_Thread_active_stacktrace_offset = 1480; + AOT_Thread_active_stacktrace_offset = 1408; static constexpr dart::compiler::target::word AOT_Thread_array_write_barrier_code_offset = 240; static constexpr dart::compiler::target::word - AOT_Thread_array_write_barrier_entry_point_offset = 536; + AOT_Thread_array_write_barrier_entry_point_offset = 528; static constexpr dart::compiler::target::word - AOT_Thread_allocate_mint_with_fpu_regs_entry_point_offset = 552; + AOT_Thread_allocate_mint_with_fpu_regs_entry_point_offset = 544; static constexpr dart::compiler::target::word - AOT_Thread_allocate_mint_with_fpu_regs_stub_offset = 368; + AOT_Thread_allocate_mint_with_fpu_regs_stub_offset = 360; static constexpr dart::compiler::target::word - AOT_Thread_allocate_mint_without_fpu_regs_entry_point_offset = 560; + AOT_Thread_allocate_mint_without_fpu_regs_entry_point_offset = 552; static constexpr dart::compiler::target::word - AOT_Thread_allocate_mint_without_fpu_regs_stub_offset = 376; + AOT_Thread_allocate_mint_without_fpu_regs_stub_offset = 368; static constexpr dart::compiler::target::word - AOT_Thread_allocate_object_entry_point_offset = 568; + AOT_Thread_allocate_object_entry_point_offset = 560; static constexpr dart::compiler::target::word - AOT_Thread_allocate_object_stub_offset = 384; + AOT_Thread_allocate_object_stub_offset = 376; static constexpr dart::compiler::target::word - AOT_Thread_allocate_object_parameterized_entry_point_offset = 576; + AOT_Thread_allocate_object_parameterized_entry_point_offset = 568; static constexpr dart::compiler::target::word - AOT_Thread_allocate_object_parameterized_stub_offset = 392; + AOT_Thread_allocate_object_parameterized_stub_offset = 384; static constexpr dart::compiler::target::word - AOT_Thread_allocate_object_slow_entry_point_offset = 584; + AOT_Thread_allocate_object_slow_entry_point_offset = 576; static constexpr dart::compiler::target::word - AOT_Thread_allocate_object_slow_stub_offset = 400; + AOT_Thread_allocate_object_slow_stub_offset = 392; static constexpr dart::compiler::target::word AOT_Thread_api_top_scope_offset = - 1544; + 1472; static constexpr dart::compiler::target::word AOT_Thread_async_stack_trace_offset = 192; static constexpr dart::compiler::target::word - AOT_Thread_auto_scope_native_wrapper_entry_point_offset = 672; + AOT_Thread_auto_scope_native_wrapper_entry_point_offset = 664; static constexpr dart::compiler::target::word AOT_Thread_bool_false_offset = 224; static constexpr dart::compiler::target::word AOT_Thread_bool_true_offset = 216; static constexpr dart::compiler::target::word - AOT_Thread_bootstrap_native_wrapper_entry_point_offset = 656; + AOT_Thread_bootstrap_native_wrapper_entry_point_offset = 648; static constexpr dart::compiler::target::word - AOT_Thread_call_to_runtime_entry_point_offset = 544; + AOT_Thread_call_to_runtime_entry_point_offset = 536; static constexpr dart::compiler::target::word - AOT_Thread_call_to_runtime_stub_offset = 280; + AOT_Thread_call_to_runtime_stub_offset = 272; static constexpr dart::compiler::target::word AOT_Thread_dart_stream_offset = - 1560; + 1488; static constexpr dart::compiler::target::word AOT_Thread_dispatch_table_array_offset = 96; static constexpr dart::compiler::target::word AOT_Thread_optimize_entry_offset = - 624; + 616; static constexpr dart::compiler::target::word AOT_Thread_optimize_stub_offset = - 456; + 448; static constexpr dart::compiler::target::word - AOT_Thread_deoptimize_entry_offset = 632; + AOT_Thread_deoptimize_entry_offset = 624; static constexpr dart::compiler::target::word - AOT_Thread_deoptimize_stub_offset = 464; + AOT_Thread_deoptimize_stub_offset = 456; static constexpr dart::compiler::target::word - AOT_Thread_double_abs_address_offset = 712; + AOT_Thread_double_abs_address_offset = 696; static constexpr dart::compiler::target::word - AOT_Thread_double_negate_address_offset = 704; + AOT_Thread_double_negate_address_offset = 688; static constexpr dart::compiler::target::word AOT_Thread_end_offset = 112; static constexpr dart::compiler::target::word - AOT_Thread_enter_safepoint_stub_offset = 504; + AOT_Thread_enter_safepoint_stub_offset = 496; static constexpr dart::compiler::target::word - AOT_Thread_execution_state_offset = 1512; + AOT_Thread_execution_state_offset = 1440; static constexpr dart::compiler::target::word - AOT_Thread_exit_safepoint_stub_offset = 512; + AOT_Thread_exit_safepoint_stub_offset = 504; static constexpr dart::compiler::target::word - AOT_Thread_call_native_through_safepoint_stub_offset = 520; + AOT_Thread_call_native_through_safepoint_stub_offset = 512; static constexpr dart::compiler::target::word - AOT_Thread_call_native_through_safepoint_entry_point_offset = 640; + AOT_Thread_call_native_through_safepoint_entry_point_offset = 632; static constexpr dart::compiler::target::word AOT_Thread_fix_allocation_stub_code_offset = 256; static constexpr dart::compiler::target::word AOT_Thread_fix_callers_target_code_offset = 248; static constexpr dart::compiler::target::word - AOT_Thread_float_absolute_address_offset = 736; + AOT_Thread_float_absolute_address_offset = 720; static constexpr dart::compiler::target::word - AOT_Thread_float_negate_address_offset = 728; + AOT_Thread_float_negate_address_offset = 712; static constexpr dart::compiler::target::word - AOT_Thread_float_not_address_offset = 720; + AOT_Thread_float_not_address_offset = 704; static constexpr dart::compiler::target::word - AOT_Thread_float_zerow_address_offset = 744; + AOT_Thread_float_zerow_address_offset = 728; static constexpr dart::compiler::target::word - AOT_Thread_global_object_pool_offset = 1488; -static constexpr dart::compiler::target::word - AOT_Thread_interpret_call_entry_point_offset = 680; -static constexpr dart::compiler::target::word - AOT_Thread_invoke_dart_code_from_bytecode_stub_offset = 272; + AOT_Thread_global_object_pool_offset = 1416; static constexpr dart::compiler::target::word AOT_Thread_invoke_dart_code_stub_offset = 264; static constexpr dart::compiler::target::word - AOT_Thread_exit_through_ffi_offset = 1536; + AOT_Thread_exit_through_ffi_offset = 1464; static constexpr dart::compiler::target::word AOT_Thread_isolate_offset = 88; static constexpr dart::compiler::target::word AOT_Thread_field_table_values_offset = 136; static constexpr dart::compiler::target::word - AOT_Thread_lazy_deopt_from_return_stub_offset = 472; + AOT_Thread_lazy_deopt_from_return_stub_offset = 464; static constexpr dart::compiler::target::word - AOT_Thread_lazy_deopt_from_throw_stub_offset = 480; + AOT_Thread_lazy_deopt_from_throw_stub_offset = 472; static constexpr dart::compiler::target::word - AOT_Thread_lazy_specialize_type_test_stub_offset = 496; + AOT_Thread_lazy_specialize_type_test_stub_offset = 488; static constexpr dart::compiler::target::word AOT_Thread_marking_stack_block_offset = 168; static constexpr dart::compiler::target::word - AOT_Thread_megamorphic_call_checked_entry_offset = 608; + AOT_Thread_megamorphic_call_checked_entry_offset = 600; static constexpr dart::compiler::target::word - AOT_Thread_switchable_call_miss_entry_offset = 616; + AOT_Thread_switchable_call_miss_entry_offset = 608; static constexpr dart::compiler::target::word - AOT_Thread_switchable_call_miss_stub_offset = 424; + AOT_Thread_switchable_call_miss_stub_offset = 416; static constexpr dart::compiler::target::word - AOT_Thread_no_scope_native_wrapper_entry_point_offset = 664; + AOT_Thread_no_scope_native_wrapper_entry_point_offset = 656; static constexpr dart::compiler::target::word - AOT_Thread_late_initialization_error_shared_with_fpu_regs_stub_offset = 296; + AOT_Thread_late_initialization_error_shared_with_fpu_regs_stub_offset = 288; static constexpr dart::compiler::target::word AOT_Thread_late_initialization_error_shared_without_fpu_regs_stub_offset = - 288; + 280; static constexpr dart::compiler::target::word - AOT_Thread_null_error_shared_with_fpu_regs_stub_offset = 312; + AOT_Thread_null_error_shared_with_fpu_regs_stub_offset = 304; static constexpr dart::compiler::target::word - AOT_Thread_null_error_shared_without_fpu_regs_stub_offset = 304; + AOT_Thread_null_error_shared_without_fpu_regs_stub_offset = 296; static constexpr dart::compiler::target::word - AOT_Thread_null_arg_error_shared_with_fpu_regs_stub_offset = 328; + AOT_Thread_null_arg_error_shared_with_fpu_regs_stub_offset = 320; static constexpr dart::compiler::target::word - AOT_Thread_null_arg_error_shared_without_fpu_regs_stub_offset = 320; + AOT_Thread_null_arg_error_shared_without_fpu_regs_stub_offset = 312; static constexpr dart::compiler::target::word - AOT_Thread_null_cast_error_shared_with_fpu_regs_stub_offset = 344; + AOT_Thread_null_cast_error_shared_with_fpu_regs_stub_offset = 336; static constexpr dart::compiler::target::word - AOT_Thread_null_cast_error_shared_without_fpu_regs_stub_offset = 336; + AOT_Thread_null_cast_error_shared_without_fpu_regs_stub_offset = 328; static constexpr dart::compiler::target::word - AOT_Thread_range_error_shared_with_fpu_regs_stub_offset = 360; + AOT_Thread_range_error_shared_with_fpu_regs_stub_offset = 352; static constexpr dart::compiler::target::word - AOT_Thread_range_error_shared_without_fpu_regs_stub_offset = 352; + AOT_Thread_range_error_shared_without_fpu_regs_stub_offset = 344; static constexpr dart::compiler::target::word AOT_Thread_object_null_offset = 208; static constexpr dart::compiler::target::word - AOT_Thread_predefined_symbols_address_offset = 688; + AOT_Thread_predefined_symbols_address_offset = 672; static constexpr dart::compiler::target::word AOT_Thread_resume_pc_offset = - 1496; + 1424; static constexpr dart::compiler::target::word - AOT_Thread_saved_shadow_call_stack_offset = 1504; + AOT_Thread_saved_shadow_call_stack_offset = 1432; static constexpr dart::compiler::target::word - AOT_Thread_safepoint_state_offset = 1520; + AOT_Thread_safepoint_state_offset = 1448; static constexpr dart::compiler::target::word - AOT_Thread_slow_type_test_stub_offset = 488; + AOT_Thread_slow_type_test_stub_offset = 480; static constexpr dart::compiler::target::word - AOT_Thread_slow_type_test_entry_point_offset = 648; + AOT_Thread_slow_type_test_entry_point_offset = 640; static constexpr dart::compiler::target::word AOT_Thread_stack_limit_offset = 72; static constexpr dart::compiler::target::word @@ -6873,13 +6785,13 @@ static constexpr dart::compiler::target::word static constexpr dart::compiler::target::word AOT_Thread_stack_overflow_flags_offset = 128; static constexpr dart::compiler::target::word - AOT_Thread_stack_overflow_shared_with_fpu_regs_entry_point_offset = 600; + AOT_Thread_stack_overflow_shared_with_fpu_regs_entry_point_offset = 592; static constexpr dart::compiler::target::word - AOT_Thread_stack_overflow_shared_with_fpu_regs_stub_offset = 416; + AOT_Thread_stack_overflow_shared_with_fpu_regs_stub_offset = 408; static constexpr dart::compiler::target::word - AOT_Thread_stack_overflow_shared_without_fpu_regs_entry_point_offset = 592; + AOT_Thread_stack_overflow_shared_without_fpu_regs_entry_point_offset = 584; static constexpr dart::compiler::target::word - AOT_Thread_stack_overflow_shared_without_fpu_regs_stub_offset = 408; + AOT_Thread_stack_overflow_shared_without_fpu_regs_stub_offset = 400; static constexpr dart::compiler::target::word AOT_Thread_store_buffer_block_offset = 160; static constexpr dart::compiler::target::word @@ -6893,11 +6805,11 @@ static constexpr dart::compiler::target::word AOT_Thread_vm_tag_offset = 184; static constexpr dart::compiler::target::word AOT_Thread_write_barrier_code_offset = 232; static constexpr dart::compiler::target::word - AOT_Thread_write_barrier_entry_point_offset = 528; + AOT_Thread_write_barrier_entry_point_offset = 520; static constexpr dart::compiler::target::word AOT_Thread_write_barrier_mask_offset = 80; static constexpr dart::compiler::target::word AOT_Thread_callback_code_offset = - 1528; + 1456; static constexpr dart::compiler::target::word AOT_TimelineStream_enabled_offset = 16; static constexpr dart::compiler::target::word AOT_TwoByteString_data_offset = @@ -6957,13 +6869,12 @@ static constexpr dart::compiler::target::word AOT_Code_entry_point_offset[] = { 8, 24, 16, 32}; static constexpr dart::compiler::target::word AOT_Thread_write_barrier_wrappers_thread_offset[] = { - 1384, 1392, 1400, 1408, -1, -1, 1416, 1424, - 1432, 1440, 1448, -1, 1456, 1464, -1, -1}; + 1312, 1320, 1328, 1336, -1, -1, 1344, 1352, + 1360, 1368, 1376, -1, 1384, 1392, -1, -1}; static constexpr dart::compiler::target::word AOT_ApiError_InstanceSize = 16; static constexpr dart::compiler::target::word AOT_Array_InstanceSize = 24; static constexpr dart::compiler::target::word AOT_Array_header_size = 24; static constexpr dart::compiler::target::word AOT_Bool_InstanceSize = 12; -static constexpr dart::compiler::target::word AOT_Bytecode_InstanceSize = 80; static constexpr dart::compiler::target::word AOT_Capability_InstanceSize = 16; static constexpr dart::compiler::target::word AOT_Class_InstanceSize = 192; static constexpr dart::compiler::target::word AOT_Closure_InstanceSize = 56; @@ -7005,7 +6916,7 @@ static constexpr dart::compiler::target::word static constexpr dart::compiler::target::word AOT_Int32x4_InstanceSize = 24; static constexpr dart::compiler::target::word AOT_Integer_InstanceSize = 8; static constexpr dart::compiler::target::word - AOT_KernelProgramInfo_InstanceSize = 128; + AOT_KernelProgramInfo_InstanceSize = 120; static constexpr dart::compiler::target::word AOT_LanguageError_InstanceSize = 48; static constexpr dart::compiler::target::word AOT_Library_InstanceSize = 152; @@ -7030,8 +6941,6 @@ static constexpr dart::compiler::target::word AOT_Object_InstanceSize = 8; static constexpr dart::compiler::target::word AOT_ObjectPool_InstanceSize = 16; static constexpr dart::compiler::target::word AOT_OneByteString_InstanceSize = 16; -static constexpr dart::compiler::target::word - AOT_ParameterTypeCheck_InstanceSize = 48; static constexpr dart::compiler::target::word AOT_PatchClass_InstanceSize = 40; static constexpr dart::compiler::target::word AOT_PcDescriptors_HeaderSize = 16; static constexpr dart::compiler::target::word AOT_Pointer_InstanceSize = 24; @@ -7296,153 +7205,149 @@ static constexpr dart::compiler::target::word AOT_String_length_offset = 8; static constexpr dart::compiler::target::word AOT_SubtypeTestCache_cache_offset = 8; static constexpr dart::compiler::target::word - AOT_Thread_AllocateArray_entry_point_offset = 752; + AOT_Thread_AllocateArray_entry_point_offset = 736; static constexpr dart::compiler::target::word - AOT_Thread_active_exception_offset = 1544; + AOT_Thread_active_exception_offset = 1472; static constexpr dart::compiler::target::word - AOT_Thread_active_stacktrace_offset = 1552; + AOT_Thread_active_stacktrace_offset = 1480; static constexpr dart::compiler::target::word AOT_Thread_array_write_barrier_code_offset = 240; static constexpr dart::compiler::target::word - AOT_Thread_array_write_barrier_entry_point_offset = 536; + AOT_Thread_array_write_barrier_entry_point_offset = 528; static constexpr dart::compiler::target::word - AOT_Thread_allocate_mint_with_fpu_regs_entry_point_offset = 552; + AOT_Thread_allocate_mint_with_fpu_regs_entry_point_offset = 544; static constexpr dart::compiler::target::word - AOT_Thread_allocate_mint_with_fpu_regs_stub_offset = 368; + AOT_Thread_allocate_mint_with_fpu_regs_stub_offset = 360; static constexpr dart::compiler::target::word - AOT_Thread_allocate_mint_without_fpu_regs_entry_point_offset = 560; + AOT_Thread_allocate_mint_without_fpu_regs_entry_point_offset = 552; static constexpr dart::compiler::target::word - AOT_Thread_allocate_mint_without_fpu_regs_stub_offset = 376; + AOT_Thread_allocate_mint_without_fpu_regs_stub_offset = 368; static constexpr dart::compiler::target::word - AOT_Thread_allocate_object_entry_point_offset = 568; + AOT_Thread_allocate_object_entry_point_offset = 560; static constexpr dart::compiler::target::word - AOT_Thread_allocate_object_stub_offset = 384; + AOT_Thread_allocate_object_stub_offset = 376; static constexpr dart::compiler::target::word - AOT_Thread_allocate_object_parameterized_entry_point_offset = 576; + AOT_Thread_allocate_object_parameterized_entry_point_offset = 568; static constexpr dart::compiler::target::word - AOT_Thread_allocate_object_parameterized_stub_offset = 392; + AOT_Thread_allocate_object_parameterized_stub_offset = 384; static constexpr dart::compiler::target::word - AOT_Thread_allocate_object_slow_entry_point_offset = 584; + AOT_Thread_allocate_object_slow_entry_point_offset = 576; static constexpr dart::compiler::target::word - AOT_Thread_allocate_object_slow_stub_offset = 400; + AOT_Thread_allocate_object_slow_stub_offset = 392; static constexpr dart::compiler::target::word AOT_Thread_api_top_scope_offset = - 1616; + 1544; static constexpr dart::compiler::target::word AOT_Thread_async_stack_trace_offset = 192; static constexpr dart::compiler::target::word - AOT_Thread_auto_scope_native_wrapper_entry_point_offset = 672; + AOT_Thread_auto_scope_native_wrapper_entry_point_offset = 664; static constexpr dart::compiler::target::word AOT_Thread_bool_false_offset = 224; static constexpr dart::compiler::target::word AOT_Thread_bool_true_offset = 216; static constexpr dart::compiler::target::word - AOT_Thread_bootstrap_native_wrapper_entry_point_offset = 656; + AOT_Thread_bootstrap_native_wrapper_entry_point_offset = 648; static constexpr dart::compiler::target::word - AOT_Thread_call_to_runtime_entry_point_offset = 544; + AOT_Thread_call_to_runtime_entry_point_offset = 536; static constexpr dart::compiler::target::word - AOT_Thread_call_to_runtime_stub_offset = 280; + AOT_Thread_call_to_runtime_stub_offset = 272; static constexpr dart::compiler::target::word AOT_Thread_dart_stream_offset = - 1632; + 1560; static constexpr dart::compiler::target::word AOT_Thread_dispatch_table_array_offset = 96; static constexpr dart::compiler::target::word AOT_Thread_optimize_entry_offset = - 624; + 616; static constexpr dart::compiler::target::word AOT_Thread_optimize_stub_offset = - 456; + 448; static constexpr dart::compiler::target::word - AOT_Thread_deoptimize_entry_offset = 632; + AOT_Thread_deoptimize_entry_offset = 624; static constexpr dart::compiler::target::word - AOT_Thread_deoptimize_stub_offset = 464; + AOT_Thread_deoptimize_stub_offset = 456; static constexpr dart::compiler::target::word - AOT_Thread_double_abs_address_offset = 712; + AOT_Thread_double_abs_address_offset = 696; static constexpr dart::compiler::target::word - AOT_Thread_double_negate_address_offset = 704; + AOT_Thread_double_negate_address_offset = 688; static constexpr dart::compiler::target::word AOT_Thread_end_offset = 112; static constexpr dart::compiler::target::word - AOT_Thread_enter_safepoint_stub_offset = 504; + AOT_Thread_enter_safepoint_stub_offset = 496; static constexpr dart::compiler::target::word - AOT_Thread_execution_state_offset = 1584; + AOT_Thread_execution_state_offset = 1512; static constexpr dart::compiler::target::word - AOT_Thread_exit_safepoint_stub_offset = 512; + AOT_Thread_exit_safepoint_stub_offset = 504; static constexpr dart::compiler::target::word - AOT_Thread_call_native_through_safepoint_stub_offset = 520; + AOT_Thread_call_native_through_safepoint_stub_offset = 512; static constexpr dart::compiler::target::word - AOT_Thread_call_native_through_safepoint_entry_point_offset = 640; + AOT_Thread_call_native_through_safepoint_entry_point_offset = 632; static constexpr dart::compiler::target::word AOT_Thread_fix_allocation_stub_code_offset = 256; static constexpr dart::compiler::target::word AOT_Thread_fix_callers_target_code_offset = 248; static constexpr dart::compiler::target::word - AOT_Thread_float_absolute_address_offset = 736; + AOT_Thread_float_absolute_address_offset = 720; static constexpr dart::compiler::target::word - AOT_Thread_float_negate_address_offset = 728; + AOT_Thread_float_negate_address_offset = 712; static constexpr dart::compiler::target::word - AOT_Thread_float_not_address_offset = 720; + AOT_Thread_float_not_address_offset = 704; static constexpr dart::compiler::target::word - AOT_Thread_float_zerow_address_offset = 744; + AOT_Thread_float_zerow_address_offset = 728; static constexpr dart::compiler::target::word - AOT_Thread_global_object_pool_offset = 1560; -static constexpr dart::compiler::target::word - AOT_Thread_interpret_call_entry_point_offset = 680; -static constexpr dart::compiler::target::word - AOT_Thread_invoke_dart_code_from_bytecode_stub_offset = 272; + AOT_Thread_global_object_pool_offset = 1488; static constexpr dart::compiler::target::word AOT_Thread_invoke_dart_code_stub_offset = 264; static constexpr dart::compiler::target::word - AOT_Thread_exit_through_ffi_offset = 1608; + AOT_Thread_exit_through_ffi_offset = 1536; static constexpr dart::compiler::target::word AOT_Thread_isolate_offset = 88; static constexpr dart::compiler::target::word AOT_Thread_field_table_values_offset = 136; static constexpr dart::compiler::target::word - AOT_Thread_lazy_deopt_from_return_stub_offset = 472; + AOT_Thread_lazy_deopt_from_return_stub_offset = 464; static constexpr dart::compiler::target::word - AOT_Thread_lazy_deopt_from_throw_stub_offset = 480; + AOT_Thread_lazy_deopt_from_throw_stub_offset = 472; static constexpr dart::compiler::target::word - AOT_Thread_lazy_specialize_type_test_stub_offset = 496; + AOT_Thread_lazy_specialize_type_test_stub_offset = 488; static constexpr dart::compiler::target::word AOT_Thread_marking_stack_block_offset = 168; static constexpr dart::compiler::target::word - AOT_Thread_megamorphic_call_checked_entry_offset = 608; + AOT_Thread_megamorphic_call_checked_entry_offset = 600; static constexpr dart::compiler::target::word - AOT_Thread_switchable_call_miss_entry_offset = 616; + AOT_Thread_switchable_call_miss_entry_offset = 608; static constexpr dart::compiler::target::word - AOT_Thread_switchable_call_miss_stub_offset = 424; + AOT_Thread_switchable_call_miss_stub_offset = 416; static constexpr dart::compiler::target::word - AOT_Thread_no_scope_native_wrapper_entry_point_offset = 664; + AOT_Thread_no_scope_native_wrapper_entry_point_offset = 656; static constexpr dart::compiler::target::word - AOT_Thread_late_initialization_error_shared_with_fpu_regs_stub_offset = 296; + AOT_Thread_late_initialization_error_shared_with_fpu_regs_stub_offset = 288; static constexpr dart::compiler::target::word AOT_Thread_late_initialization_error_shared_without_fpu_regs_stub_offset = - 288; + 280; static constexpr dart::compiler::target::word - AOT_Thread_null_error_shared_with_fpu_regs_stub_offset = 312; + AOT_Thread_null_error_shared_with_fpu_regs_stub_offset = 304; static constexpr dart::compiler::target::word - AOT_Thread_null_error_shared_without_fpu_regs_stub_offset = 304; + AOT_Thread_null_error_shared_without_fpu_regs_stub_offset = 296; static constexpr dart::compiler::target::word - AOT_Thread_null_arg_error_shared_with_fpu_regs_stub_offset = 328; + AOT_Thread_null_arg_error_shared_with_fpu_regs_stub_offset = 320; static constexpr dart::compiler::target::word - AOT_Thread_null_arg_error_shared_without_fpu_regs_stub_offset = 320; + AOT_Thread_null_arg_error_shared_without_fpu_regs_stub_offset = 312; static constexpr dart::compiler::target::word - AOT_Thread_null_cast_error_shared_with_fpu_regs_stub_offset = 344; + AOT_Thread_null_cast_error_shared_with_fpu_regs_stub_offset = 336; static constexpr dart::compiler::target::word - AOT_Thread_null_cast_error_shared_without_fpu_regs_stub_offset = 336; + AOT_Thread_null_cast_error_shared_without_fpu_regs_stub_offset = 328; static constexpr dart::compiler::target::word - AOT_Thread_range_error_shared_with_fpu_regs_stub_offset = 360; + AOT_Thread_range_error_shared_with_fpu_regs_stub_offset = 352; static constexpr dart::compiler::target::word - AOT_Thread_range_error_shared_without_fpu_regs_stub_offset = 352; + AOT_Thread_range_error_shared_without_fpu_regs_stub_offset = 344; static constexpr dart::compiler::target::word AOT_Thread_object_null_offset = 208; static constexpr dart::compiler::target::word - AOT_Thread_predefined_symbols_address_offset = 688; + AOT_Thread_predefined_symbols_address_offset = 672; static constexpr dart::compiler::target::word AOT_Thread_resume_pc_offset = - 1568; + 1496; static constexpr dart::compiler::target::word - AOT_Thread_saved_shadow_call_stack_offset = 1576; + AOT_Thread_saved_shadow_call_stack_offset = 1504; static constexpr dart::compiler::target::word - AOT_Thread_safepoint_state_offset = 1592; + AOT_Thread_safepoint_state_offset = 1520; static constexpr dart::compiler::target::word - AOT_Thread_slow_type_test_stub_offset = 488; + AOT_Thread_slow_type_test_stub_offset = 480; static constexpr dart::compiler::target::word - AOT_Thread_slow_type_test_entry_point_offset = 648; + AOT_Thread_slow_type_test_entry_point_offset = 640; static constexpr dart::compiler::target::word AOT_Thread_stack_limit_offset = 72; static constexpr dart::compiler::target::word @@ -7450,13 +7355,13 @@ static constexpr dart::compiler::target::word static constexpr dart::compiler::target::word AOT_Thread_stack_overflow_flags_offset = 128; static constexpr dart::compiler::target::word - AOT_Thread_stack_overflow_shared_with_fpu_regs_entry_point_offset = 600; + AOT_Thread_stack_overflow_shared_with_fpu_regs_entry_point_offset = 592; static constexpr dart::compiler::target::word - AOT_Thread_stack_overflow_shared_with_fpu_regs_stub_offset = 416; + AOT_Thread_stack_overflow_shared_with_fpu_regs_stub_offset = 408; static constexpr dart::compiler::target::word - AOT_Thread_stack_overflow_shared_without_fpu_regs_entry_point_offset = 592; + AOT_Thread_stack_overflow_shared_without_fpu_regs_entry_point_offset = 584; static constexpr dart::compiler::target::word - AOT_Thread_stack_overflow_shared_without_fpu_regs_stub_offset = 408; + AOT_Thread_stack_overflow_shared_without_fpu_regs_stub_offset = 400; static constexpr dart::compiler::target::word AOT_Thread_store_buffer_block_offset = 160; static constexpr dart::compiler::target::word @@ -7470,11 +7375,11 @@ static constexpr dart::compiler::target::word AOT_Thread_vm_tag_offset = 184; static constexpr dart::compiler::target::word AOT_Thread_write_barrier_code_offset = 232; static constexpr dart::compiler::target::word - AOT_Thread_write_barrier_entry_point_offset = 528; + AOT_Thread_write_barrier_entry_point_offset = 520; static constexpr dart::compiler::target::word AOT_Thread_write_barrier_mask_offset = 80; static constexpr dart::compiler::target::word AOT_Thread_callback_code_offset = - 1600; + 1528; static constexpr dart::compiler::target::word AOT_TimelineStream_enabled_offset = 16; static constexpr dart::compiler::target::word AOT_TwoByteString_data_offset = @@ -7534,14 +7439,13 @@ static constexpr dart::compiler::target::word AOT_Code_entry_point_offset[] = { 8, 24, 16, 32}; static constexpr dart::compiler::target::word AOT_Thread_write_barrier_wrappers_thread_offset[] = { - 1384, 1392, 1400, 1408, 1416, 1424, 1432, 1440, 1448, 1456, 1464, - 1472, 1480, 1488, 1496, -1, -1, -1, -1, 1504, 1512, -1, - -1, 1520, 1528, 1536, -1, -1, -1, -1, -1, -1}; + 1312, 1320, 1328, 1336, 1344, 1352, 1360, 1368, 1376, 1384, 1392, + 1400, 1408, 1416, 1424, -1, -1, -1, -1, 1432, 1440, -1, + -1, 1448, 1456, 1464, -1, -1, -1, -1, -1, -1}; static constexpr dart::compiler::target::word AOT_ApiError_InstanceSize = 16; static constexpr dart::compiler::target::word AOT_Array_InstanceSize = 24; static constexpr dart::compiler::target::word AOT_Array_header_size = 24; static constexpr dart::compiler::target::word AOT_Bool_InstanceSize = 12; -static constexpr dart::compiler::target::word AOT_Bytecode_InstanceSize = 80; static constexpr dart::compiler::target::word AOT_Capability_InstanceSize = 16; static constexpr dart::compiler::target::word AOT_Class_InstanceSize = 192; static constexpr dart::compiler::target::word AOT_Closure_InstanceSize = 56; @@ -7583,7 +7487,7 @@ static constexpr dart::compiler::target::word static constexpr dart::compiler::target::word AOT_Int32x4_InstanceSize = 24; static constexpr dart::compiler::target::word AOT_Integer_InstanceSize = 8; static constexpr dart::compiler::target::word - AOT_KernelProgramInfo_InstanceSize = 128; + AOT_KernelProgramInfo_InstanceSize = 120; static constexpr dart::compiler::target::word AOT_LanguageError_InstanceSize = 48; static constexpr dart::compiler::target::word AOT_Library_InstanceSize = 152; @@ -7608,8 +7512,6 @@ static constexpr dart::compiler::target::word AOT_Object_InstanceSize = 8; static constexpr dart::compiler::target::word AOT_ObjectPool_InstanceSize = 16; static constexpr dart::compiler::target::word AOT_OneByteString_InstanceSize = 16; -static constexpr dart::compiler::target::word - AOT_ParameterTypeCheck_InstanceSize = 48; static constexpr dart::compiler::target::word AOT_PatchClass_InstanceSize = 40; static constexpr dart::compiler::target::word AOT_PcDescriptors_HeaderSize = 16; static constexpr dart::compiler::target::word AOT_Pointer_InstanceSize = 24; diff --git a/runtime/vm/compiler/runtime_offsets_list.h b/runtime/vm/compiler/runtime_offsets_list.h index 60398309e04..2aa714c751d 100644 --- a/runtime/vm/compiler/runtime_offsets_list.h +++ b/runtime/vm/compiler/runtime_offsets_list.h @@ -208,8 +208,6 @@ FIELD(Thread, float_not_address_offset) \ FIELD(Thread, float_zerow_address_offset) \ FIELD(Thread, global_object_pool_offset) \ - FIELD(Thread, interpret_call_entry_point_offset) \ - FIELD(Thread, invoke_dart_code_from_bytecode_stub_offset) \ FIELD(Thread, invoke_dart_code_stub_offset) \ FIELD(Thread, exit_through_ffi_offset) \ FIELD(Thread, isolate_offset) \ @@ -301,7 +299,6 @@ SIZEOF(Array, InstanceSize, ArrayLayout) \ SIZEOF(Array, header_size, ArrayLayout) \ SIZEOF(Bool, InstanceSize, BoolLayout) \ - SIZEOF(Bytecode, InstanceSize, BytecodeLayout) \ SIZEOF(Capability, InstanceSize, CapabilityLayout) \ SIZEOF(Class, InstanceSize, ClassLayout) \ SIZEOF(Closure, InstanceSize, ClosureLayout) \ @@ -347,7 +344,6 @@ SIZEOF(Object, InstanceSize, ObjectLayout) \ SIZEOF(ObjectPool, InstanceSize, ObjectPoolLayout) \ SIZEOF(OneByteString, InstanceSize, OneByteStringLayout) \ - SIZEOF(ParameterTypeCheck, InstanceSize, ParameterTypeCheckLayout) \ SIZEOF(PatchClass, InstanceSize, PatchClassLayout) \ SIZEOF(PcDescriptors, HeaderSize, PcDescriptorsLayout) \ SIZEOF(Pointer, InstanceSize, PointerLayout) \ diff --git a/runtime/vm/compiler/stub_code_compiler.cc b/runtime/vm/compiler/stub_code_compiler.cc index 547cf925a2c..4376d54e787 100644 --- a/runtime/vm/compiler/stub_code_compiler.cc +++ b/runtime/vm/compiler/stub_code_compiler.cc @@ -84,14 +84,8 @@ void StubCodeCompiler::GenerateInitLateInstanceFieldStub(Assembler* assembler, if (!FLAG_precompiled_mode || !FLAG_use_bare_instructions) { __ LoadField(CODE_REG, FieldAddress(kFunctionReg, target::Function::code_offset())); - if (FLAG_enable_interpreter) { - // InterpretCall stub needs arguments descriptor for all function calls. - __ LoadObject(ARGS_DESC_REG, - CastHandle(OneArgArgumentsDescriptor())); - } else { - // Load a GC-safe value for the arguments descriptor (unused but tagged). - __ LoadImmediate(ARGS_DESC_REG, 0); - } + // Load a GC-safe value for the arguments descriptor (unused but tagged). + __ LoadImmediate(ARGS_DESC_REG, 0); } __ Call(FieldAddress(kFunctionReg, target::Function::entry_point_offset())); __ Drop(1); // Drop argument. diff --git a/runtime/vm/compiler/stub_code_compiler_arm.cc b/runtime/vm/compiler/stub_code_compiler_arm.cc index fef56a00812..141f3788075 100644 --- a/runtime/vm/compiler/stub_code_compiler_arm.cc +++ b/runtime/vm/compiler/stub_code_compiler_arm.cc @@ -96,7 +96,7 @@ void StubCodeCompiler::GenerateCallToRuntimeStub(Assembler* assembler) { Label ok; // Check that we are always entering from Dart code. __ LoadFromOffset(kWord, R8, THR, target::Thread::vm_tag_offset()); - __ CompareImmediate(R8, VMTag::kDartCompiledTagId); + __ CompareImmediate(R8, VMTag::kDartTagId); __ b(&ok, EQ); __ Stop("Not coming from Dart code."); __ Bind(&ok); @@ -137,7 +137,7 @@ void StubCodeCompiler::GenerateCallToRuntimeStub(Assembler* assembler) { __ blx(R9); // Mark that the thread is executing Dart code. - __ LoadImmediate(R2, VMTag::kDartCompiledTagId); + __ LoadImmediate(R2, VMTag::kDartTagId); __ StoreToOffset(kWord, R2, THR, target::Thread::vm_tag_offset()); // Mark that the thread has not exited generated Dart code. @@ -540,7 +540,7 @@ static void GenerateCallNativeWithWrapperStub(Assembler* assembler, Label ok; // Check that we are always entering from Dart code. __ LoadFromOffset(kWord, R8, THR, target::Thread::vm_tag_offset()); - __ CompareImmediate(R8, VMTag::kDartCompiledTagId); + __ CompareImmediate(R8, VMTag::kDartTagId); __ b(&ok, EQ); __ Stop("Not coming from Dart code."); __ Bind(&ok); @@ -587,7 +587,7 @@ static void GenerateCallNativeWithWrapperStub(Assembler* assembler, __ blx(LR); // Mark that the thread is executing Dart code. - __ LoadImmediate(R2, VMTag::kDartCompiledTagId); + __ LoadImmediate(R2, VMTag::kDartTagId); __ StoreToOffset(kWord, R2, THR, target::Thread::vm_tag_offset()); // Mark that the thread has not exited generated Dart code. @@ -1230,7 +1230,7 @@ void StubCodeCompiler::GenerateInvokeDartCodeStub(Assembler* assembler) { // Mark that the thread is executing Dart code. Do this after initializing the // exit link for the profiler. - __ LoadImmediate(R9, VMTag::kDartCompiledTagId); + __ LoadImmediate(R9, VMTag::kDartTagId); __ StoreToOffset(kWord, R9, THR, target::Thread::vm_tag_offset()); // Load arguments descriptor array into R4, which is passed to Dart code. @@ -1307,160 +1307,6 @@ void StubCodeCompiler::GenerateInvokeDartCodeStub(Assembler* assembler) { __ Ret(); } -// Called when invoking compiled Dart code from interpreted Dart code. -// Input parameters: -// LR : points to return address. -// R0 : raw code object of the Dart function to call. -// R1 : arguments raw descriptor array. -// R2 : address of first argument. -// R3 : current thread. -void StubCodeCompiler::GenerateInvokeDartCodeFromBytecodeStub( - Assembler* assembler) { - if (FLAG_precompiled_mode) { - __ Stop("Not using interpreter"); - return; - } - - __ Push(LR); // Marker for the profiler. - __ EnterFrame((1 << FP) | (1 << LR), 0); - - // Push code object to PC marker slot. - __ ldr(IP, - Address(R3, - target::Thread::invoke_dart_code_from_bytecode_stub_offset())); - __ Push(IP); - - // Save new context and C++ ABI callee-saved registers. - __ PushList(kAbiPreservedCpuRegs); - - const DRegister firstd = EvenDRegisterOf(kAbiFirstPreservedFpuReg); - if (TargetCPUFeatures::vfp_supported()) { - ASSERT(2 * kAbiPreservedFpuRegCount < 16); - // Save FPU registers. 2 D registers per Q register. - __ vstmd(DB_W, SP, firstd, 2 * kAbiPreservedFpuRegCount); - } else { - __ sub(SP, SP, Operand(kAbiPreservedFpuRegCount * kFpuRegisterSize)); - } - - // Set up THR, which caches the current thread in Dart code. - if (THR != R3) { - __ mov(THR, Operand(R3)); - } - -#if defined(USING_SHADOW_CALL_STACK) -#error Unimplemented -#endif - - // Save the current VMTag on the stack. - __ LoadFromOffset(kWord, R9, THR, target::Thread::vm_tag_offset()); - __ Push(R9); - - // Save top resource and top exit frame info. Use R4-6 as temporary registers. - // StackFrameIterator reads the top exit frame info saved in this frame. - __ LoadFromOffset(kWord, R4, THR, target::Thread::top_resource_offset()); - __ Push(R4); - __ LoadImmediate(R8, 0); - __ StoreToOffset(kWord, R8, THR, target::Thread::top_resource_offset()); - - __ LoadFromOffset(kWord, R8, THR, target::Thread::exit_through_ffi_offset()); - __ Push(R8); - __ LoadImmediate(R8, 0); - __ StoreToOffset(kWord, R8, THR, target::Thread::exit_through_ffi_offset()); - - __ LoadFromOffset(kWord, R9, THR, - target::Thread::top_exit_frame_info_offset()); - __ StoreToOffset(kWord, R8, THR, - target::Thread::top_exit_frame_info_offset()); - - // target::frame_layout.exit_link_slot_from_entry_fp must be kept in sync - // with the code below. -#if defined(TARGET_OS_MACOS) || defined(TARGET_OS_MACOS_IOS) - ASSERT(target::frame_layout.exit_link_slot_from_entry_fp == -27); -#else - ASSERT(target::frame_layout.exit_link_slot_from_entry_fp == -28); -#endif - __ Push(R9); - - // Mark that the thread is executing Dart code. Do this after initializing the - // exit link for the profiler. - __ LoadImmediate(R9, VMTag::kDartCompiledTagId); - __ StoreToOffset(kWord, R9, THR, target::Thread::vm_tag_offset()); - - // Load arguments descriptor array into R4, which is passed to Dart code. - __ mov(R4, Operand(R1)); - - // Load number of arguments into R9 and adjust count for type arguments. - __ ldr(R3, - FieldAddress(R4, target::ArgumentsDescriptor::type_args_len_offset())); - __ ldr(R9, FieldAddress(R4, target::ArgumentsDescriptor::count_offset())); - __ cmp(R3, Operand(0)); - __ AddImmediate(R9, R9, target::ToRawSmi(1), - NE); // Include the type arguments. - __ SmiUntag(R9); - - // R2 points to first argument. - // Set up arguments for the Dart call. - Label push_arguments; - Label done_push_arguments; - __ CompareImmediate(R9, 0); // check if there are arguments. - __ b(&done_push_arguments, EQ); - __ LoadImmediate(R1, 0); - __ Bind(&push_arguments); - __ ldr(R3, Address(R2)); - __ Push(R3); - __ AddImmediate(R2, target::kWordSize); - __ AddImmediate(R1, 1); - __ cmp(R1, Operand(R9)); - __ b(&push_arguments, LT); - __ Bind(&done_push_arguments); - - // Call the Dart code entrypoint. - __ LoadImmediate(PP, 0); // GC safe value into PP. - __ mov(CODE_REG, Operand(R0)); - __ ldr(R0, FieldAddress(CODE_REG, target::Code::entry_point_offset())); - __ blx(R0); // R4 is the arguments descriptor array. - - // Get rid of arguments pushed on the stack. - __ AddImmediate( - SP, FP, - target::frame_layout.exit_link_slot_from_entry_fp * target::kWordSize); - - // Restore the saved top exit frame info and top resource back into the - // Isolate structure. Uses R9 as a temporary register for this. - __ Pop(R9); - __ StoreToOffset(kWord, R9, THR, - target::Thread::top_exit_frame_info_offset()); - __ Pop(R9); - __ StoreToOffset(kWord, R9, THR, target::Thread::exit_through_ffi_offset()); - __ Pop(R9); - __ StoreToOffset(kWord, R9, THR, target::Thread::top_resource_offset()); - - // Restore the current VMTag from the stack. - __ Pop(R4); - __ StoreToOffset(kWord, R4, THR, target::Thread::vm_tag_offset()); - - // Restore C++ ABI callee-saved registers. - if (TargetCPUFeatures::vfp_supported()) { - // Restore FPU registers. 2 D registers per Q register. - __ vldmd(IA_W, SP, firstd, 2 * kAbiPreservedFpuRegCount); - } else { - __ AddImmediate(SP, kAbiPreservedFpuRegCount * kFpuRegisterSize); - } - -#if defined(USING_SHADOW_CALL_STACK) -#error Unimplemented -#endif - - // Restore CPU registers. - __ PopList(kAbiPreservedCpuRegs); - __ set_constant_pool_allowed(false); - - // Restore the frame pointer and return. - __ LeaveFrame((1 << FP) | (1 << LR)); - __ Drop(1); - __ Ret(); -} - // Helper to generate space allocation of context stub. // This does not initialise the fields of the context. // Input: @@ -2695,94 +2541,10 @@ void StubCodeCompiler::GenerateLazyCompileStub(Assembler* assembler) { __ PopList((1 << R0) | (1 << R4)); __ LeaveStubFrame(); - // When using the interpreter, the function's code may now point to the - // InterpretCall stub. Make sure R0, R4 and R9 are preserved. __ ldr(CODE_REG, FieldAddress(R0, target::Function::code_offset())); __ Branch(FieldAddress(R0, target::Function::entry_point_offset())); } -// Stub for interpreting a function call. -// R4: Arguments descriptor. -// R0: Function. -void StubCodeCompiler::GenerateInterpretCallStub(Assembler* assembler) { - if (FLAG_precompiled_mode) { - __ Stop("Not using interpreter"); - return; - } - __ EnterStubFrame(); - -#if defined(DEBUG) - { - Label ok; - // Check that we are always entering from Dart code. - __ LoadFromOffset(kWord, R8, THR, target::Thread::vm_tag_offset()); - __ CompareImmediate(R8, VMTag::kDartCompiledTagId); - __ b(&ok, EQ); - __ Stop("Not coming from Dart code."); - __ Bind(&ok); - } -#endif - - // Adjust arguments count for type arguments vector. - __ LoadFieldFromOffset(kWord, R2, R4, - target::ArgumentsDescriptor::count_offset()); - __ SmiUntag(R2); - __ LoadFieldFromOffset(kWord, R1, R4, - target::ArgumentsDescriptor::type_args_len_offset()); - __ cmp(R1, Operand(0)); - __ AddImmediate(R2, R2, 1, NE); // Include the type arguments. - - // Compute argv. - __ mov(R3, Operand(R2, LSL, 2)); - __ add(R3, FP, Operand(R3)); - __ AddImmediate(R3, - target::frame_layout.param_end_from_fp * target::kWordSize); - - // Indicate decreasing memory addresses of arguments with negative argc. - __ rsb(R2, R2, Operand(0)); - - // Align frame before entering C++ world. Fifth argument passed on the stack. - __ ReserveAlignedFrameSpace(1 * target::kWordSize); - - // Pass arguments in registers. - // R0: Function. - __ mov(R1, Operand(R4)); // Arguments descriptor. - // R2: Negative argc. - // R3: Argv. - __ str(THR, Address(SP, 0)); // Fifth argument: Thread. - - // Save exit frame information to enable stack walking as we are about - // to transition to Dart VM C++ code. - __ StoreToOffset(kWord, FP, THR, - target::Thread::top_exit_frame_info_offset()); - - // Mark that the thread exited generated code through a runtime call. - __ LoadImmediate(R5, target::Thread::exit_through_runtime_call()); - __ StoreToOffset(kWord, R5, THR, target::Thread::exit_through_ffi_offset()); - - // Mark that the thread is executing VM code. - __ LoadFromOffset(kWord, R5, THR, - target::Thread::interpret_call_entry_point_offset()); - __ StoreToOffset(kWord, R5, THR, target::Thread::vm_tag_offset()); - - __ blx(R5); - - // Mark that the thread is executing Dart code. - __ LoadImmediate(R2, VMTag::kDartCompiledTagId); - __ StoreToOffset(kWord, R2, THR, target::Thread::vm_tag_offset()); - - // Mark that the thread has not exited generated Dart code. - __ LoadImmediate(R2, 0); - __ StoreToOffset(kWord, R2, THR, target::Thread::exit_through_ffi_offset()); - - // Reset exit frame information in Isolate's mutator thread structure. - __ StoreToOffset(kWord, R2, THR, - target::Thread::top_exit_frame_info_offset()); - - __ LeaveStubFrame(); - __ Ret(); -} - // R9: Contains an ICData. void StubCodeCompiler::GenerateICCallBreakpointStub(Assembler* assembler) { #if defined(PRODUCT) @@ -3318,7 +3080,7 @@ void StubCodeCompiler::GenerateJumpToFrameStub(Assembler* assembler) { __ Bind(&exit_through_non_ffi); // Set the tag. - __ LoadImmediate(R2, VMTag::kDartCompiledTagId); + __ LoadImmediate(R2, VMTag::kDartTagId); __ StoreToOffset(kWord, R2, THR, target::Thread::vm_tag_offset()); // Clear top exit frame. __ LoadImmediate(R2, 0); diff --git a/runtime/vm/compiler/stub_code_compiler_arm64.cc b/runtime/vm/compiler/stub_code_compiler_arm64.cc index 6548ef8616d..b749ad92060 100644 --- a/runtime/vm/compiler/stub_code_compiler_arm64.cc +++ b/runtime/vm/compiler/stub_code_compiler_arm64.cc @@ -91,7 +91,7 @@ void StubCodeCompiler::GenerateCallToRuntimeStub(Assembler* assembler) { Label ok; // Check that we are always entering from Dart code. __ LoadFromOffset(R8, THR, target::Thread::vm_tag_offset()); - __ CompareImmediate(R8, VMTag::kDartCompiledTagId); + __ CompareImmediate(R8, VMTag::kDartTagId); __ b(&ok, EQ); __ Stop("Not coming from Dart code."); __ Bind(&ok); @@ -154,7 +154,7 @@ void StubCodeCompiler::GenerateCallToRuntimeStub(Assembler* assembler) { // Retval is next to 1st argument. // Mark that the thread is executing Dart code. - __ LoadImmediate(R2, VMTag::kDartCompiledTagId); + __ LoadImmediate(R2, VMTag::kDartTagId); __ StoreToOffset(R2, THR, target::Thread::vm_tag_offset()); // Mark that the thread has not exited generated Dart code. @@ -622,7 +622,7 @@ static void GenerateCallNativeWithWrapperStub(Assembler* assembler, Label ok; // Check that we are always entering from Dart code. __ LoadFromOffset(R6, THR, target::Thread::vm_tag_offset()); - __ CompareImmediate(R6, VMTag::kDartCompiledTagId); + __ CompareImmediate(R6, VMTag::kDartTagId); __ b(&ok, EQ); __ Stop("Not coming from Dart code."); __ Bind(&ok); @@ -685,7 +685,7 @@ static void GenerateCallNativeWithWrapperStub(Assembler* assembler, __ RestorePinnedRegisters(); // Mark that the thread is executing Dart code. - __ LoadImmediate(R2, VMTag::kDartCompiledTagId); + __ LoadImmediate(R2, VMTag::kDartTagId); __ StoreToOffset(R2, THR, target::Thread::vm_tag_offset()); // Mark that the thread has not exited generated Dart code. @@ -1358,7 +1358,7 @@ void StubCodeCompiler::GenerateInvokeDartCodeStub(Assembler* assembler) { // Mark that the thread is executing Dart code. Do this after initializing the // exit link for the profiler. - __ LoadImmediate(R6, VMTag::kDartCompiledTagId); + __ LoadImmediate(R6, VMTag::kDartTagId); __ StoreToOffset(R6, THR, target::Thread::vm_tag_offset()); // Load arguments descriptor array into R4, which is passed to Dart code. @@ -1444,157 +1444,6 @@ void StubCodeCompiler::GenerateInvokeDartCodeStub(Assembler* assembler) { __ ret(); } -// Called when invoking compiled Dart code from interpreted Dart code. -// Input parameters: -// LR : points to return address. -// R0 : raw code object of the Dart function to call. -// R1 : arguments raw descriptor array. -// R2 : address of first argument. -// R3 : current thread. -void StubCodeCompiler::GenerateInvokeDartCodeFromBytecodeStub( - Assembler* assembler) { - if (FLAG_precompiled_mode) { - __ Stop("Not using interpreter"); - return; - } - - // Copy the C stack pointer (CSP/R31) into the stack pointer we'll actually - // use to access the stack (SP/R15) and set the C stack pointer to near the - // stack limit, loaded from the Thread held in R3, to prevent signal handlers - // from over-writing Dart frames. - __ mov(SP, CSP); - __ SetupCSPFromThread(R3); - __ Push(LR); // Marker for the profiler. - __ EnterFrame(0); - - // Push code object to PC marker slot. - __ ldr(TMP, - Address(R3, - target::Thread::invoke_dart_code_from_bytecode_stub_offset())); - __ Push(TMP); - -#if defined(TARGET_OS_FUCHSIA) - __ str(R18, Address(R3, target::Thread::saved_shadow_call_stack_offset())); -#elif defined(USING_SHADOW_CALL_STACK) -#error Unimplemented -#endif - - __ PushNativeCalleeSavedRegisters(); - - // Set up THR, which caches the current thread in Dart code. - if (THR != R3) { - __ mov(THR, R3); - } - - // Refresh pinned registers values (inc. write barrier mask and null object). - __ RestorePinnedRegisters(); - - // Save the current VMTag on the stack. - __ LoadFromOffset(R4, THR, target::Thread::vm_tag_offset()); - __ Push(R4); - - // Save top resource and top exit frame info. Use R6 as a temporary register. - // StackFrameIterator reads the top exit frame info saved in this frame. - __ LoadFromOffset(R6, THR, target::Thread::top_resource_offset()); - __ StoreToOffset(ZR, THR, target::Thread::top_resource_offset()); - __ Push(R6); - - __ LoadFromOffset(R6, THR, target::Thread::exit_through_ffi_offset()); - __ Push(R6); - __ LoadImmediate(R6, 0); - __ StoreToOffset(R6, THR, target::Thread::exit_through_ffi_offset()); - - __ LoadFromOffset(R6, THR, target::Thread::top_exit_frame_info_offset()); - __ StoreToOffset(ZR, THR, target::Thread::top_exit_frame_info_offset()); - // target::frame_layout.exit_link_slot_from_entry_fp must be kept in sync - // with the code below. -#if defined(TARGET_OS_FUCHSIA) - ASSERT(target::frame_layout.exit_link_slot_from_entry_fp == -24); -#else - ASSERT(target::frame_layout.exit_link_slot_from_entry_fp == -23); -#endif - __ Push(R6); - - // Mark that the thread is executing Dart code. Do this after initializing the - // exit link for the profiler. - __ LoadImmediate(R6, VMTag::kDartCompiledTagId); - __ StoreToOffset(R6, THR, target::Thread::vm_tag_offset()); - - // Load arguments descriptor array into R4, which is passed to Dart code. - __ mov(R4, R1); - - // Load number of arguments into R5 and adjust count for type arguments. - __ LoadFieldFromOffset(R5, R4, target::ArgumentsDescriptor::count_offset()); - __ LoadFieldFromOffset(R3, R4, - target::ArgumentsDescriptor::type_args_len_offset()); - __ AddImmediate(TMP, R5, 1); // Include the type arguments. - __ cmp(R3, Operand(0)); - __ csinc(R5, R5, TMP, EQ); // R5 <- (R3 == 0) ? R5 : TMP + 1 (R5 : R5 + 2). - __ SmiUntag(R5); - - // R2 points to first argument. - // Set up arguments for the Dart call. - Label push_arguments; - Label done_push_arguments; - __ cmp(R5, Operand(0)); - __ b(&done_push_arguments, EQ); // check if there are arguments. - __ LoadImmediate(R1, 0); - __ Bind(&push_arguments); - __ ldr(R3, Address(R2)); - __ Push(R3); - __ add(R1, R1, Operand(1)); - __ add(R2, R2, Operand(target::kWordSize)); - __ cmp(R1, Operand(R5)); - __ b(&push_arguments, LT); - __ Bind(&done_push_arguments); - - // We now load the pool pointer(PP) with a GC safe value as we are about to - // invoke dart code. We don't need a real object pool here. - // Smi zero does not work because ARM64 assumes PP to be untagged. - __ LoadObject(PP, NullObject()); - - // Call the Dart code entrypoint. - __ mov(CODE_REG, R0); - __ ldr(R0, FieldAddress(CODE_REG, target::Code::entry_point_offset())); - __ blr(R0); // R4 is the arguments descriptor array. - - // Get rid of arguments pushed on the stack. - __ AddImmediate( - SP, FP, - target::frame_layout.exit_link_slot_from_entry_fp * target::kWordSize); - - // Restore the saved top exit frame info and top resource back into the - // Isolate structure. Uses R6 as a temporary register for this. - __ Pop(R6); - __ StoreToOffset(R6, THR, target::Thread::top_exit_frame_info_offset()); - __ Pop(R6); - __ StoreToOffset(R6, THR, target::Thread::exit_through_ffi_offset()); - __ Pop(R6); - __ StoreToOffset(R6, THR, target::Thread::top_resource_offset()); - - // Restore the current VMTag from the stack. - __ Pop(R4); - __ StoreToOffset(R4, THR, target::Thread::vm_tag_offset()); - -#if defined(TARGET_OS_FUCHSIA) - __ mov(R3, THR); -#endif - - __ PopNativeCalleeSavedRegisters(); // Clobbers THR - -#if defined(TARGET_OS_FUCHSIA) - __ str(R18, Address(R3, target::Thread::saved_shadow_call_stack_offset())); -#elif defined(USING_SHADOW_CALL_STACK) -#error Unimplemented -#endif - - // Restore the frame pointer and C stack pointer and return. - __ LeaveFrame(); - __ Drop(1); - __ RestoreCSP(); - __ ret(); -} - // Helper to generate space allocation of context stub. // This does not initialise the fields of the context. // Input: @@ -2858,106 +2707,11 @@ void StubCodeCompiler::GenerateLazyCompileStub(Assembler* assembler) { __ Pop(R4); // Restore arg desc. __ LeaveStubFrame(); - // When using the interpreter, the function's code may now point to the - // InterpretCall stub. Make sure R0, R4, and R5 are preserved. __ LoadFieldFromOffset(CODE_REG, R0, target::Function::code_offset()); __ LoadFieldFromOffset(R2, R0, target::Function::entry_point_offset()); __ br(R2); } -// Stub for interpreting a function call. -// R4: Arguments descriptor. -// R0: Function. -void StubCodeCompiler::GenerateInterpretCallStub(Assembler* assembler) { - if (FLAG_precompiled_mode) { - __ Stop("Not using interpreter"); - return; - } - - __ SetPrologueOffset(); - __ EnterStubFrame(); - -#if defined(DEBUG) - { - Label ok; - // Check that we are always entering from Dart code. - __ LoadFromOffset(R8, THR, target::Thread::vm_tag_offset()); - __ CompareImmediate(R8, VMTag::kDartCompiledTagId); - __ b(&ok, EQ); - __ Stop("Not coming from Dart code."); - __ Bind(&ok); - } -#endif - - // Adjust arguments count for type arguments vector. - __ LoadFieldFromOffset(R2, R4, target::ArgumentsDescriptor::count_offset()); - __ SmiUntag(R2); - __ LoadFieldFromOffset(R1, R4, - target::ArgumentsDescriptor::type_args_len_offset()); - __ cmp(R1, Operand(0)); - __ csinc(R2, R2, R2, EQ); // R2 <- (R1 == 0) ? R2 : R2 + 1. - - // Compute argv. - __ add(R3, ZR, Operand(R2, LSL, 3)); - __ add(R3, FP, Operand(R3)); - __ AddImmediate(R3, - target::frame_layout.param_end_from_fp * target::kWordSize); - - // Indicate decreasing memory addresses of arguments with negative argc. - __ neg(R2, R2); - - // Align frame before entering C++ world. No shadow stack space required. - __ ReserveAlignedFrameSpace(0 * target::kWordSize); - - // Pass arguments in registers. - // R0: Function. - __ mov(R1, R4); // Arguments descriptor. - // R2: Negative argc. - // R3: Argv. - __ mov(R4, THR); // Thread. - - // Save exit frame information to enable stack walking as we are about - // to transition to Dart VM C++ code. - __ StoreToOffset(FP, THR, target::Thread::top_exit_frame_info_offset()); - - // Mark that the thread exited generated code through a runtime call. - __ LoadImmediate(R5, target::Thread::exit_through_runtime_call()); - __ StoreToOffset(R5, THR, target::Thread::exit_through_ffi_offset()); - - // Mark that the thread is executing VM code. - __ LoadFromOffset(R5, THR, - target::Thread::interpret_call_entry_point_offset()); - __ StoreToOffset(R5, THR, target::Thread::vm_tag_offset()); - - // We are entering runtime code, so the C stack pointer must be restored from - // the stack limit to the top of the stack. We cache the stack limit address - // in a callee-saved register. - __ mov(R25, CSP); - __ mov(CSP, SP); - - __ blr(R5); - - // Restore SP and CSP. - __ mov(SP, CSP); - __ mov(CSP, R25); - - // Refresh pinned registers values (inc. write barrier mask and null object). - __ RestorePinnedRegisters(); - - // Mark that the thread is executing Dart code. - __ LoadImmediate(R2, VMTag::kDartCompiledTagId); - __ StoreToOffset(R2, THR, target::Thread::vm_tag_offset()); - - // Mark that the thread has not exited generated Dart code. - __ StoreToOffset(ZR, THR, target::Thread::exit_through_ffi_offset()); - - // Reset exit frame information in Isolate's mutator thread structure. - __ StoreToOffset(ZR, THR, target::Thread::top_exit_frame_info_offset()); - - __ LeaveStubFrame(); - __ ret(); -} - // R5: Contains an ICData. void StubCodeCompiler::GenerateICCallBreakpointStub(Assembler* assembler) { #if defined(PRODUCT) @@ -3484,7 +3238,7 @@ void StubCodeCompiler::GenerateJumpToFrameStub(Assembler* assembler) { // Refresh pinned registers values (inc. write barrier mask and null object). __ RestorePinnedRegisters(); // Set the tag. - __ LoadImmediate(R2, VMTag::kDartCompiledTagId); + __ LoadImmediate(R2, VMTag::kDartTagId); __ StoreToOffset(R2, THR, target::Thread::vm_tag_offset()); // Clear top exit frame. __ StoreToOffset(ZR, THR, target::Thread::top_exit_frame_info_offset()); diff --git a/runtime/vm/compiler/stub_code_compiler_ia32.cc b/runtime/vm/compiler/stub_code_compiler_ia32.cc index e3eeed6f85d..bc4c54502e5 100644 --- a/runtime/vm/compiler/stub_code_compiler_ia32.cc +++ b/runtime/vm/compiler/stub_code_compiler_ia32.cc @@ -93,7 +93,7 @@ void StubCodeCompiler::GenerateCallToRuntimeStub(Assembler* assembler) { { Label ok; // Check that we are always entering from Dart code. - __ cmpl(Assembler::VMTagAddress(), Immediate(VMTag::kDartCompiledTagId)); + __ cmpl(Assembler::VMTagAddress(), Immediate(VMTag::kDartTagId)); __ j(EQUAL, &ok, Assembler::kNearJump); __ Stop("Not coming from Dart code."); __ Bind(&ok); @@ -126,7 +126,7 @@ void StubCodeCompiler::GenerateCallToRuntimeStub(Assembler* assembler) { __ movl(Address(ESP, retval_offset), EAX); // Set retval in NativeArguments. __ call(ECX); - __ movl(Assembler::VMTagAddress(), Immediate(VMTag::kDartCompiledTagId)); + __ movl(Assembler::VMTagAddress(), Immediate(VMTag::kDartTagId)); // Mark that the thread has not exited generated Dart code. __ movl(Address(THR, target::Thread::exit_through_ffi_offset()), @@ -364,7 +364,7 @@ static void GenerateCallNativeWithWrapperStub(Assembler* assembler, { Label ok; // Check that we are always entering from Dart code. - __ cmpl(Assembler::VMTagAddress(), Immediate(VMTag::kDartCompiledTagId)); + __ cmpl(Assembler::VMTagAddress(), Immediate(VMTag::kDartTagId)); __ j(EQUAL, &ok, Assembler::kNearJump); __ Stop("Not coming from Dart code."); __ Bind(&ok); @@ -400,7 +400,7 @@ static void GenerateCallNativeWithWrapperStub(Assembler* assembler, __ movl(Address(ESP, target::kWordSize), ECX); // Function to call. __ call(wrapper_address); - __ movl(Assembler::VMTagAddress(), Immediate(VMTag::kDartCompiledTagId)); + __ movl(Assembler::VMTagAddress(), Immediate(VMTag::kDartTagId)); // Mark that the thread has not exited generated Dart code. __ movl(Address(THR, target::Thread::exit_through_ffi_offset()), @@ -955,7 +955,7 @@ void StubCodeCompiler::GenerateInvokeDartCodeStub(Assembler* assembler) { // Mark that the thread is executing Dart code. Do this after initializing the // exit link for the profiler. - __ movl(Assembler::VMTagAddress(), Immediate(VMTag::kDartCompiledTagId)); + __ movl(Assembler::VMTagAddress(), Immediate(VMTag::kDartTagId)); // Load arguments descriptor array into EDX. __ movl(EDX, Address(EBP, kArgumentsDescOffset)); @@ -1029,134 +1029,6 @@ void StubCodeCompiler::GenerateInvokeDartCodeStub(Assembler* assembler) { __ ret(); } -// Called when invoking compiled Dart code from interpreted Dart code. -// Input parameters: -// ESP : points to return address. -// ESP + 4 : target raw code -// ESP + 8 : arguments raw descriptor array. -// ESP + 12: address of first argument. -// ESP + 16 : current thread. -void StubCodeCompiler::GenerateInvokeDartCodeFromBytecodeStub( - Assembler* assembler) { - const intptr_t kTargetCodeOffset = 3 * target::kWordSize; - const intptr_t kArgumentsDescOffset = 4 * target::kWordSize; - const intptr_t kArgumentsOffset = 5 * target::kWordSize; - const intptr_t kThreadOffset = 6 * target::kWordSize; - - __ pushl(Address(ESP, 0)); // Marker for the profiler. - __ EnterFrame(0); - - // Push code object to PC marker slot. - __ movl(EAX, Address(EBP, kThreadOffset)); - __ pushl(Address(EAX, target::Thread::invoke_dart_code_stub_offset())); - - // Save C++ ABI callee-saved registers. - __ pushl(EBX); - __ pushl(ESI); - __ pushl(EDI); - - // Set up THR, which caches the current thread in Dart code. - __ movl(THR, EAX); - -#if defined(USING_SHADOW_CALL_STACK) -#error Unimplemented -#endif - - // Save the current VMTag on the stack. - __ movl(ECX, Assembler::VMTagAddress()); - __ pushl(ECX); - - // Save top resource and top exit frame info. Use EDX as a temporary register. - // StackFrameIterator reads the top exit frame info saved in this frame. - __ movl(EDX, Address(THR, target::Thread::top_resource_offset())); - __ pushl(EDX); - __ movl(Address(THR, target::Thread::top_resource_offset()), Immediate(0)); - - __ movl(EAX, Address(THR, target::Thread::exit_through_ffi_offset())); - __ pushl(EAX); - __ movl(Address(THR, target::Thread::exit_through_ffi_offset()), - Immediate(0)); - - // The constant target::frame_layout.exit_link_slot_from_entry_fp must be - // kept in sync with the code below. - ASSERT(target::frame_layout.exit_link_slot_from_entry_fp == -8); - __ movl(EDX, Address(THR, target::Thread::top_exit_frame_info_offset())); - __ pushl(EDX); - __ movl(Address(THR, target::Thread::top_exit_frame_info_offset()), - Immediate(0)); - - // Mark that the thread is executing Dart code. Do this after initializing the - // exit link for the profiler. - __ movl(Assembler::VMTagAddress(), Immediate(VMTag::kDartCompiledTagId)); - - // Load arguments descriptor array into EDX. - __ movl(EDX, Address(EBP, kArgumentsDescOffset)); - - // Load number of arguments into EBX and adjust count for type arguments. - __ movl(EBX, FieldAddress(EDX, target::ArgumentsDescriptor::count_offset())); - __ cmpl( - FieldAddress(EDX, target::ArgumentsDescriptor::type_args_len_offset()), - Immediate(0)); - Label args_count_ok; - __ j(EQUAL, &args_count_ok, Assembler::kNearJump); - __ addl(EBX, Immediate(target::ToRawSmi(1))); // Include the type arguments. - __ Bind(&args_count_ok); - // Save number of arguments as Smi on stack, replacing ArgumentsDesc. - __ movl(Address(EBP, kArgumentsDescOffset), EBX); - __ SmiUntag(EBX); - - // Set up arguments for the dart call. - Label push_arguments; - Label done_push_arguments; - __ testl(EBX, EBX); // check if there are arguments. - __ j(ZERO, &done_push_arguments, Assembler::kNearJump); - __ movl(EAX, Immediate(0)); - - // Compute address of 'arguments array' data area into EDI. - __ movl(EDI, Address(EBP, kArgumentsOffset)); - - __ Bind(&push_arguments); - __ movl(ECX, Address(EDI, EAX, TIMES_4, 0)); - __ pushl(ECX); - __ incl(EAX); - __ cmpl(EAX, EBX); - __ j(LESS, &push_arguments, Assembler::kNearJump); - __ Bind(&done_push_arguments); - - // Call the dart code entrypoint. - __ movl(EAX, Address(EBP, kTargetCodeOffset)); - __ call(FieldAddress(EAX, target::Code::entry_point_offset())); - - // Read the saved number of passed arguments as Smi. - __ movl(EDX, Address(EBP, kArgumentsDescOffset)); - // Get rid of arguments pushed on the stack. - __ leal(ESP, Address(ESP, EDX, TIMES_2, 0)); // EDX is a Smi. - - // Restore the saved top exit frame info and top resource back into the - // Isolate structure. - __ popl(Address(THR, target::Thread::top_exit_frame_info_offset())); - __ popl(Address(THR, target::Thread::exit_through_ffi_offset())); - __ popl(Address(THR, target::Thread::top_resource_offset())); - - // Restore the current VMTag from the stack. - __ popl(Assembler::VMTagAddress()); - -#if defined(USING_SHADOW_CALL_STACK) -#error Unimplemented -#endif - - // Restore C++ ABI callee-saved registers. - __ popl(EDI); - __ popl(ESI); - __ popl(EBX); - - // Restore the frame pointer. - __ LeaveFrame(); - __ popl(ECX); - - __ ret(); -} - // Helper to generate space allocation of context stub. // This does not initialise the fields of the context. // Input: @@ -2231,85 +2103,9 @@ void StubCodeCompiler::GenerateLazyCompileStub(Assembler* assembler) { __ popl(EDX); // Restore arguments descriptor array. __ LeaveFrame(); - // When using the interpreter, the function's code may now point to the - // InterpretCall stub. Make sure EAX, ECX, and EDX are preserved. __ jmp(FieldAddress(EAX, target::Function::entry_point_offset())); } -// Stub for interpreting a function call. -// EDX: Arguments descriptor. -// EAX: Function. -void StubCodeCompiler::GenerateInterpretCallStub(Assembler* assembler) { - __ EnterStubFrame(); - -#if defined(DEBUG) - { - Label ok; - // Check that we are always entering from Dart code. - __ cmpl(Assembler::VMTagAddress(), Immediate(VMTag::kDartCompiledTagId)); - __ j(EQUAL, &ok, Assembler::kNearJump); - __ Stop("Not coming from Dart code."); - __ Bind(&ok); - } -#endif - - // Adjust arguments count for type arguments vector. - __ movl(ECX, FieldAddress(EDX, target::ArgumentsDescriptor::count_offset())); - __ SmiUntag(ECX); - __ cmpl( - FieldAddress(EDX, target::ArgumentsDescriptor::type_args_len_offset()), - Immediate(0)); - Label args_count_ok; - __ j(EQUAL, &args_count_ok, Assembler::kNearJump); - __ incl(ECX); - __ Bind(&args_count_ok); - - // Compute argv. - __ leal(EBX, - Address(EBP, ECX, TIMES_4, - target::frame_layout.param_end_from_fp * target::kWordSize)); - - // Indicate decreasing memory addresses of arguments with negative argc. - __ negl(ECX); - - __ pushl(THR); // Arg 4: Thread. - __ pushl(EBX); // Arg 3: Argv. - __ pushl(ECX); // Arg 2: Negative argc. - __ pushl(EDX); // Arg 1: Arguments descriptor - __ pushl(EAX); // Arg 0: Function - - // Save exit frame information to enable stack walking as we are about - // to transition to Dart VM C++ code. - __ movl(Address(THR, target::Thread::top_exit_frame_info_offset()), EBP); - - // Mark that the thread exited generated code through a runtime call. - __ movl(Address(THR, target::Thread::exit_through_ffi_offset()), - Immediate(target::Thread::exit_through_runtime_call())); - - // Mark that the thread is executing VM code. - __ movl(EAX, - Address(THR, target::Thread::interpret_call_entry_point_offset())); - __ movl(Assembler::VMTagAddress(), EAX); - - __ call(EAX); - - __ Drop(5); - - // Mark that the thread is executing Dart code. - __ movl(Assembler::VMTagAddress(), Immediate(VMTag::kDartCompiledTagId)); - - // Mark that the thread has not exited generated Dart code. - __ movl(Address(THR, target::Thread::exit_through_ffi_offset()), - Immediate(0)); - - // Reset exit frame information in Isolate's mutator thread structure. - __ movl(Address(THR, target::Thread::top_exit_frame_info_offset()), - Immediate(0)); - - __ LeaveFrame(); - __ ret(); -} - // ECX: Contains an ICData. void StubCodeCompiler::GenerateICCallBreakpointStub(Assembler* assembler) { #if defined(PRODUCT) @@ -2658,7 +2454,7 @@ void StubCodeCompiler::GenerateJumpToFrameStub(Assembler* assembler) { __ Bind(&exit_through_non_ffi); // Set tag. - __ movl(Assembler::VMTagAddress(), Immediate(VMTag::kDartCompiledTagId)); + __ movl(Assembler::VMTagAddress(), Immediate(VMTag::kDartTagId)); // Clear top exit frame. __ movl(Address(THR, target::Thread::top_exit_frame_info_offset()), Immediate(0)); diff --git a/runtime/vm/compiler/stub_code_compiler_x64.cc b/runtime/vm/compiler/stub_code_compiler_x64.cc index 7af1a071963..26f82920814 100644 --- a/runtime/vm/compiler/stub_code_compiler_x64.cc +++ b/runtime/vm/compiler/stub_code_compiler_x64.cc @@ -96,7 +96,7 @@ void StubCodeCompiler::GenerateCallToRuntimeStub(Assembler* assembler) { { Label ok; // Check that we are always entering from Dart code. - __ movq(RAX, Immediate(VMTag::kDartCompiledTagId)); + __ movq(RAX, Immediate(VMTag::kDartTagId)); __ cmpq(RAX, Assembler::VMTagAddress()); __ j(EQUAL, &ok, Assembler::kNearJump); __ Stop("Not coming from Dart code."); @@ -137,7 +137,7 @@ void StubCodeCompiler::GenerateCallToRuntimeStub(Assembler* assembler) { __ CallCFunction(RBX); // Mark that the thread is executing Dart code. - __ movq(Assembler::VMTagAddress(), Immediate(VMTag::kDartCompiledTagId)); + __ movq(Assembler::VMTagAddress(), Immediate(VMTag::kDartTagId)); // Mark that the thread has not exited generated Dart code. __ movq(Address(THR, target::Thread::exit_through_ffi_offset()), @@ -575,7 +575,7 @@ static void GenerateCallNativeWithWrapperStub(Assembler* assembler, { Label ok; // Check that we are always entering from Dart code. - __ movq(R8, Immediate(VMTag::kDartCompiledTagId)); + __ movq(R8, Immediate(VMTag::kDartTagId)); __ cmpq(R8, Assembler::VMTagAddress()); __ j(EQUAL, &ok, Assembler::kNearJump); __ Stop("Not coming from Dart code."); @@ -614,7 +614,7 @@ static void GenerateCallNativeWithWrapperStub(Assembler* assembler, __ CallCFunction(RAX); // Mark that the thread is executing Dart code. - __ movq(Assembler::VMTagAddress(), Immediate(VMTag::kDartCompiledTagId)); + __ movq(Assembler::VMTagAddress(), Immediate(VMTag::kDartTagId)); // Mark that the thread has not exited generated Dart code. __ movq(Address(THR, target::Thread::exit_through_ffi_offset()), @@ -1287,7 +1287,7 @@ void StubCodeCompiler::GenerateInvokeDartCodeStub(Assembler* assembler) { // Mark that the thread is executing Dart code. Do this after initializing the // exit link for the profiler. - __ movq(Assembler::VMTagAddress(), Immediate(VMTag::kDartCompiledTagId)); + __ movq(Assembler::VMTagAddress(), Immediate(VMTag::kDartTagId)); // Load arguments descriptor array into R10, which is passed to Dart code. __ movq(R10, Address(kArgDescReg, VMHandles::kOffsetOfRawPtrInHandle)); @@ -1367,172 +1367,6 @@ void StubCodeCompiler::GenerateInvokeDartCodeStub(Assembler* assembler) { __ ret(); } -// Called when invoking compiled Dart code from interpreted Dart code. -// Input parameters: -// RSP : points to return address. -// RDI : target raw code -// RSI : arguments raw descriptor array. -// RDX : address of first argument. -// RCX : current thread. -void StubCodeCompiler::GenerateInvokeDartCodeFromBytecodeStub( - Assembler* assembler) { - if (FLAG_precompiled_mode) { - __ Stop("Not using interpreter"); - return; - } - - __ pushq(Address(RSP, 0)); // Marker for the profiler. - __ EnterFrame(0); - - const Register kTargetCodeReg = CallingConventions::kArg1Reg; - const Register kArgDescReg = CallingConventions::kArg2Reg; - const Register kArg0Reg = CallingConventions::kArg3Reg; - const Register kThreadReg = CallingConventions::kArg4Reg; - - // Push code object to PC marker slot. - __ pushq( - Address(kThreadReg, - target::Thread::invoke_dart_code_from_bytecode_stub_offset())); - - // At this point, the stack looks like: - // | stub code object - // | saved RBP | <-- RBP - // | saved PC (return to interpreter's InvokeCompiled) | - - const intptr_t kInitialOffset = 2; - // Save arguments descriptor array, later replaced by Smi argument count. - const intptr_t kArgumentsDescOffset = -(kInitialOffset)*target::kWordSize; - __ pushq(kArgDescReg); - - // Save C++ ABI callee-saved registers. - __ PushRegisters(CallingConventions::kCalleeSaveCpuRegisters, - CallingConventions::kCalleeSaveXmmRegisters); - - // If any additional (or fewer) values are pushed, the offsets in - // target::frame_layout.exit_link_slot_from_entry_fp will need to be changed. - - // Set up THR, which caches the current thread in Dart code. - if (THR != kThreadReg) { - __ movq(THR, kThreadReg); - } - -#if defined(USING_SHADOW_CALL_STACK) -#error Unimplemented -#endif - - // Save the current VMTag on the stack. - __ movq(RAX, Assembler::VMTagAddress()); - __ pushq(RAX); - - // Save top resource and top exit frame info. Use RAX as a temporary register. - // StackFrameIterator reads the top exit frame info saved in this frame. - __ movq(RAX, Address(THR, target::Thread::top_resource_offset())); - __ pushq(RAX); - __ movq(Address(THR, target::Thread::top_resource_offset()), Immediate(0)); - - __ movq(RAX, Address(THR, target::Thread::exit_through_ffi_offset())); - __ pushq(RAX); - __ movq(Address(THR, target::Thread::exit_through_ffi_offset()), - Immediate(0)); - - __ movq(RAX, Address(THR, target::Thread::top_exit_frame_info_offset())); - __ pushq(RAX); - __ movq(Address(THR, target::Thread::top_exit_frame_info_offset()), - Immediate(0)); - -// The constant target::frame_layout.exit_link_slot_from_entry_fp must be kept -// in sync with the code below. -#if defined(DEBUG) - { - Label ok; - __ leaq(RAX, - Address(RBP, target::frame_layout.exit_link_slot_from_entry_fp * - target::kWordSize)); - __ cmpq(RAX, RSP); - __ j(EQUAL, &ok); - __ Stop("target::frame_layout.exit_link_slot_from_entry_fp mismatch"); - __ Bind(&ok); - } -#endif - - // Mark that the thread is executing Dart code. Do this after initializing the - // exit link for the profiler. - __ movq(Assembler::VMTagAddress(), Immediate(VMTag::kDartCompiledTagId)); - - // Load arguments descriptor array into R10, which is passed to Dart code. - __ movq(R10, kArgDescReg); - - // Push arguments. At this point we only need to preserve kTargetCodeReg. - ASSERT(kTargetCodeReg != RDX); - - // Load number of arguments into RBX and adjust count for type arguments. - __ movq(RBX, FieldAddress(R10, target::ArgumentsDescriptor::count_offset())); - __ cmpq( - FieldAddress(R10, target::ArgumentsDescriptor::type_args_len_offset()), - Immediate(0)); - Label args_count_ok; - __ j(EQUAL, &args_count_ok, Assembler::kNearJump); - __ addq(RBX, Immediate(target::ToRawSmi(1))); // Include the type arguments. - __ Bind(&args_count_ok); - // Save number of arguments as Smi on stack, replacing saved ArgumentsDesc. - __ movq(Address(RBP, kArgumentsDescOffset), RBX); - __ SmiUntag(RBX); - - // Compute address of first argument into RDX. - if (kArg0Reg != RDX) { // Different registers on WIN64. - __ movq(RDX, kArg0Reg); - } - - // Set up arguments for the Dart call. - Label push_arguments; - Label done_push_arguments; - __ j(ZERO, &done_push_arguments, Assembler::kNearJump); - __ LoadImmediate(RAX, Immediate(0)); - __ Bind(&push_arguments); - __ pushq(Address(RDX, RAX, TIMES_8, 0)); - __ incq(RAX); - __ cmpq(RAX, RBX); - __ j(LESS, &push_arguments, Assembler::kNearJump); - __ Bind(&done_push_arguments); - - // Call the Dart code entrypoint. - __ xorq(PP, PP); // GC-safe value into PP. - __ movq(CODE_REG, kTargetCodeReg); - __ movq(kTargetCodeReg, - FieldAddress(CODE_REG, target::Code::entry_point_offset())); - __ call(kTargetCodeReg); // R10 is the arguments descriptor array. - - // Read the saved number of passed arguments as Smi. - __ movq(RDX, Address(RBP, kArgumentsDescOffset)); - - // Get rid of arguments pushed on the stack. - __ leaq(RSP, Address(RSP, RDX, TIMES_4, 0)); // RDX is a Smi. - - // Restore the saved top exit frame info and top resource back into the - // Isolate structure. - __ popq(Address(THR, target::Thread::top_exit_frame_info_offset())); - __ popq(Address(THR, target::Thread::exit_through_ffi_offset())); - __ popq(Address(THR, target::Thread::top_resource_offset())); - - // Restore the current VMTag from the stack. - __ popq(Assembler::VMTagAddress()); - -#if defined(USING_SHADOW_CALL_STACK) -#error Unimplemented -#endif - - // Restore C++ ABI callee-saved registers. - __ PopRegisters(CallingConventions::kCalleeSaveCpuRegisters, - CallingConventions::kCalleeSaveXmmRegisters); - __ set_constant_pool_allowed(false); - - // Restore the frame pointer. - __ LeaveFrame(); - __ popq(RCX); - - __ ret(); -} - // Helper to generate space allocation of context stub. // This does not initialise the fields of the context. // Input: @@ -2812,101 +2646,11 @@ void StubCodeCompiler::GenerateLazyCompileStub(Assembler* assembler) { __ popq(R10); // Restore arguments descriptor array. __ LeaveStubFrame(); - // When using the interpreter, the function's code may now point to the - // InterpretCall stub. Make sure RAX, R10, and RBX are preserved. __ movq(CODE_REG, FieldAddress(RAX, target::Function::code_offset())); __ movq(RCX, FieldAddress(RAX, target::Function::entry_point_offset())); __ jmp(RCX); } -// Stub for interpreting a function call. -// R10: Arguments descriptor. -// RAX: Function. -void StubCodeCompiler::GenerateInterpretCallStub(Assembler* assembler) { - if (FLAG_precompiled_mode) { - __ Stop("Not using interpreter"); - return; - } - - __ EnterStubFrame(); - -#if defined(DEBUG) - { - Label ok; - // Check that we are always entering from Dart code. - __ movq(R8, Immediate(VMTag::kDartCompiledTagId)); - __ cmpq(R8, Assembler::VMTagAddress()); - __ j(EQUAL, &ok, Assembler::kNearJump); - __ Stop("Not coming from Dart code."); - __ Bind(&ok); - } -#endif - - // Adjust arguments count for type arguments vector. - __ movq(R11, FieldAddress(R10, target::ArgumentsDescriptor::count_offset())); - __ SmiUntag(R11); - __ cmpq( - FieldAddress(R10, target::ArgumentsDescriptor::type_args_len_offset()), - Immediate(0)); - Label args_count_ok; - __ j(EQUAL, &args_count_ok, Assembler::kNearJump); - __ incq(R11); - __ Bind(&args_count_ok); - - // Compute argv. - __ leaq(R12, - Address(RBP, R11, TIMES_8, - target::frame_layout.param_end_from_fp * target::kWordSize)); - - // Indicate decreasing memory addresses of arguments with negative argc. - __ negq(R11); - - // Reserve shadow space for args and align frame before entering C++ world. - __ subq(RSP, Immediate(5 * target::kWordSize)); - if (OS::ActivationFrameAlignment() > 1) { - __ andq(RSP, Immediate(~(OS::ActivationFrameAlignment() - 1))); - } - - __ movq(CallingConventions::kArg1Reg, RAX); // Function. - __ movq(CallingConventions::kArg2Reg, R10); // Arguments descriptor. - __ movq(CallingConventions::kArg3Reg, R11); // Negative argc. - __ movq(CallingConventions::kArg4Reg, R12); // Argv. - -#if defined(TARGET_OS_WINDOWS) - __ movq(Address(RSP, 0 * target::kWordSize), THR); // Thread. -#else - __ movq(CallingConventions::kArg5Reg, THR); // Thread. -#endif - // Save exit frame information to enable stack walking as we are about - // to transition to Dart VM C++ code. - __ movq(Address(THR, target::Thread::top_exit_frame_info_offset()), RBP); - - // Mark that the thread exited generated code through a runtime call. - __ movq(Address(THR, target::Thread::exit_through_ffi_offset()), - Immediate(target::Thread::exit_through_runtime_call())); - - // Mark that the thread is executing VM code. - __ movq(RAX, - Address(THR, target::Thread::interpret_call_entry_point_offset())); - __ movq(Assembler::VMTagAddress(), RAX); - - __ call(RAX); - - // Mark that the thread is executing Dart code. - __ movq(Assembler::VMTagAddress(), Immediate(VMTag::kDartCompiledTagId)); - - // Mark that the thread has not exited generated Dart code. - __ movq(Address(THR, target::Thread::exit_through_ffi_offset()), - Immediate(0)); - - // Reset exit frame information in Isolate's mutator thread structure. - __ movq(Address(THR, target::Thread::top_exit_frame_info_offset()), - Immediate(0)); - - __ LeaveStubFrame(); - __ ret(); -} - // RBX: Contains an ICData. // TOS(0): return address (Dart code). void StubCodeCompiler::GenerateICCallBreakpointStub(Assembler* assembler) { @@ -3422,7 +3166,7 @@ void StubCodeCompiler::GenerateJumpToFrameStub(Assembler* assembler) { __ Bind(&exit_through_non_ffi); // Set the tag. - __ movq(Assembler::VMTagAddress(), Immediate(VMTag::kDartCompiledTagId)); + __ movq(Assembler::VMTagAddress(), Immediate(VMTag::kDartTagId)); // Clear top exit frame. __ movq(Address(THR, target::Thread::top_exit_frame_info_offset()), Immediate(0)); diff --git a/runtime/vm/compiler_test.cc b/runtime/vm/compiler_test.cc index 219dc7c50b9..1a5afc1a4c0 100644 --- a/runtime/vm/compiler_test.cc +++ b/runtime/vm/compiler_test.cc @@ -6,7 +6,6 @@ #include "platform/assert.h" #include "vm/class_finalizer.h" #include "vm/code_patcher.h" -#include "vm/compiler/frontend/bytecode_reader.h" #include "vm/dart_api_impl.h" #include "vm/heap/safepoint.h" #include "vm/kernel_isolate.h" @@ -126,30 +125,8 @@ ISOLATE_UNIT_TEST_CASE(CompileFunctionOnHelperThread) { Function& func = Function::Handle(cls.LookupStaticFunction(function_foo_name)); EXPECT(!func.HasCode()); - if (!FLAG_enable_interpreter) { - CompilerTest::TestCompileFunction(func); - EXPECT(func.HasCode()); - return; - } - // Bytecode loading must happen on the main thread. Ensure the bytecode is - // loaded before asking for an unoptimized compile on a background thread. - kernel::BytecodeReader::ReadFunctionBytecode(thread, func); -#if !defined(PRODUCT) - // Constant in product mode. - FLAG_background_compilation = true; -#endif - Isolate* isolate = thread->isolate(); - BackgroundCompiler::Start(isolate); - isolate->background_compiler()->Compile(func); - Monitor* m = new Monitor(); - { - MonitorLocker ml(m); - while (!func.HasCode()) { - ml.WaitWithSafepointCheck(thread, 1); - } - } - delete m; - BackgroundCompiler::Stop(isolate); + CompilerTest::TestCompileFunction(func); + EXPECT(func.HasCode()); } ISOLATE_UNIT_TEST_CASE(RegenerateAllocStubs) { diff --git a/runtime/vm/constants_kbc.cc b/runtime/vm/constants_kbc.cc deleted file mode 100644 index adbe04219c0..00000000000 --- a/runtime/vm/constants_kbc.cc +++ /dev/null @@ -1,76 +0,0 @@ -// Copyright (c) 2019, the Dart project authors. Please see the AUTHORS file -// for details. All rights reserved. Use of this source code is governed by a -// BSD-style license that can be found in the LICENSE file. - -#define RUNTIME_VM_CONSTANTS_H_ // To work around include guard. -#include "vm/constants_kbc.h" - -namespace dart { - -static const intptr_t kInstructionSize0 = 1; -static const intptr_t kInstructionSizeA = 2; -static const intptr_t kInstructionSizeD = 2; -static const intptr_t kInstructionSizeWideD = 5; -static const intptr_t kInstructionSizeX = 2; -static const intptr_t kInstructionSizeWideX = 5; -static const intptr_t kInstructionSizeT = 2; -static const intptr_t kInstructionSizeWideT = 4; -static const intptr_t kInstructionSizeA_E = 3; -static const intptr_t kInstructionSizeWideA_E = 6; -static const intptr_t kInstructionSizeA_Y = 3; -static const intptr_t kInstructionSizeWideA_Y = 6; -static const intptr_t kInstructionSizeD_F = 3; -static const intptr_t kInstructionSizeWideD_F = 6; -static const intptr_t kInstructionSizeA_B_C = 4; - -const intptr_t KernelBytecode::kInstructionSize[] = { -#define SIZE_ORDN(encoding) kInstructionSize##encoding -#define SIZE_WIDE(encoding) kInstructionSizeWide##encoding -#define SIZE_RESV(encoding) SIZE_ORDN(encoding) -#define SIZE(name, encoding, kind, op1, op2, op3) SIZE_##kind(encoding), - KERNEL_BYTECODES_LIST(SIZE) -#undef SIZE_ORDN -#undef SIZE_WIDE -#undef SIZE_RESV -#undef SIZE -}; - -#define DECLARE_INSTRUCTIONS(name, fmt, kind, fmta, fmtb, fmtc) \ - static const KBCInstr k##name##Instructions[] = { \ - KernelBytecode::k##name, \ - KernelBytecode::kReturnTOS, \ - }; -INTERNAL_KERNEL_BYTECODES_LIST(DECLARE_INSTRUCTIONS) -#undef DECLARE_INSTRUCTIONS - -void KernelBytecode::GetVMInternalBytecodeInstructions( - Opcode opcode, - const KBCInstr** instructions, - intptr_t* instructions_size) { - switch (opcode) { -#define CASE(name, fmt, kind, fmta, fmtb, fmtc) \ - case k##name: \ - *instructions = k##name##Instructions; \ - *instructions_size = sizeof(k##name##Instructions); \ - return; - - INTERNAL_KERNEL_BYTECODES_LIST(CASE) -#undef CASE - - default: - UNREACHABLE(); - } -} - -static const KBCInstr kNativeCallToGrowableListReturnTrampoline[] = { - KernelBytecode::kDirectCall, - 0, // target (doesn't matter) - KernelBytecode::kNativeCallToGrowableListArgc, // number of arguments - KernelBytecode::kReturnTOS, -}; - -const KBCInstr* KernelBytecode::GetNativeCallToGrowableListReturnTrampoline() { - return KernelBytecode::Next(&kNativeCallToGrowableListReturnTrampoline[0]); -} - -} // namespace dart diff --git a/runtime/vm/constants_kbc.h b/runtime/vm/constants_kbc.h deleted file mode 100644 index cae8a9740ff..00000000000 --- a/runtime/vm/constants_kbc.h +++ /dev/null @@ -1,1076 +0,0 @@ -// Copyright (c) 2018, the Dart project authors. Please see the AUTHORS file -// for details. All rights reserved. Use of this source code is governed by a -// BSD-style license that can be found in the LICENSE file. - -#ifndef RUNTIME_VM_CONSTANTS_KBC_H_ -#define RUNTIME_VM_CONSTANTS_KBC_H_ - -#include "platform/assert.h" -#include "platform/globals.h" -#include "platform/utils.h" - -namespace dart { - -// clang-format off -// List of KernelBytecode instructions. -// -// INTERPRETER STATE -// -// current frame info (see stack_frame_kbc.h for layout) -// v-----^-----v -// ~----+----~ ~----+-------+-------+-~ ~-+-------+-------+-~ -// ~ | ~ ~ | FP[0] | FP[1] | ~ ~ | SP[-1]| SP[0] | -// ~----+----~ ~----+-------+-------+-~ ~-+-------+-------+-~ -// ^ ^ -// FP SP -// -// -// The state of execution is captured in few interpreter registers: -// -// FP - base of the current frame -// SP - top of the stack (TOS) for the current frame -// PP - object pool for the currently execution function -// -// Frame info stored below FP additionally contains pointers to the currently -// executing function and code. -// -// In the unoptimized code most of bytecodes take operands implicitly from -// stack and store results again on the stack. Constant operands are usually -// taken from the object pool by index. -// -// ENCODING -// -// Each instruction starts with opcode byte. Certain instructions have -// wide encoding variant. In such case, the least significant bit of opcode is -// not set for compact variant and set for wide variant. -// -// The following operand encodings are used: -// -// 0........8.......16.......24.......32.......40.......48 -// +--------+ -// | opcode | 0: no operands -// +--------+ -// -// +--------+--------+ -// | opcode | A | A: unsigned 8-bit operand -// +--------+--------+ -// -// +--------+--------+ -// | opcode | D | D: unsigned 8/32-bit operand -// +--------+--------+ -// -// +--------+----------------------------------+ -// | opcode | D | D (wide) -// +--------+----------------------------------+ -// -// +--------+--------+ -// | opcode | X | X: signed 8/32-bit operand -// +--------+--------+ -// -// +--------+----------------------------------+ -// | opcode | X | X (wide) -// +--------+----------------------------------+ -// -// +--------+--------+ -// | opcode | T | T: signed 8/24-bit operand -// +--------+--------+ -// -// +--------+--------------------------+ -// | opcode | T | T (wide) -// +--------+--------------------------+ -// -// +--------+--------+--------+ -// | opcode | A | E | A_E: unsigned 8-bit operand and -// +--------+--------+--------+ unsigned 8/32-bit operand -// -// +--------+--------+----------------------------------+ -// | opcode | A | E | A_E (wide) -// +--------+--------+----------------------------------+ -// -// +--------+--------+--------+ -// | opcode | A | Y | A_Y: unsigned 8-bit operand and -// +--------+--------+--------+ signed 8/32-bit operand -// -// +--------+--------+----------------------------------+ -// | opcode | A | Y | A_Y (wide) -// +--------+--------+----------------------------------+ -// -// +--------+--------+--------+ -// | opcode | D | F | D_F: unsigned 8/32-bit operand and -// +--------+--------+--------+ unsigned 8-bit operand -// -// +--------+----------------------------------+--------+ -// | opcode | D | F | D_F (wide) -// +--------+----------------------------------+--------+ -// -// +--------+--------+--------+--------+ -// | opcode | A | B | C | A_B_C: 3 unsigned 8-bit operands -// +--------+--------+--------+--------+ -// -// -// INSTRUCTIONS -// -// - Trap -// -// Unreachable instruction. -// -// - Entry rD -// -// Function prologue for the function -// rD - number of local slots to reserve; -// -// - EntryFixed A, D -// -// Function prologue for functions without optional arguments. -// Checks number of arguments. -// A - expected number of positional arguments; -// D - number of local slots to reserve; -// -// - EntryOptional A, B, C -// -// Function prologue for the function with optional or named arguments: -// A - expected number of positional arguments; -// B - number of optional arguments; -// C - number of named arguments; -// -// Only one of B and C can be not 0. -// -// If B is not 0 then EntryOptional bytecode is followed by B LoadConstant -// bytecodes specifying default values for optional arguments. -// -// If C is not 0 then EntryOptional is followed by 2 * C LoadConstant -// bytecodes. -// Bytecode at 2 * i specifies name of the i-th named argument and at -// 2 * i + 1 default value. rA part of the LoadConstant bytecode specifies -// the location of the parameter on the stack. Here named arguments are -// sorted alphabetically to enable linear matching similar to how function -// prologues are implemented on other architectures. -// -// Note: Unlike Entry bytecode EntryOptional does not setup the frame for -// local variables this is done by a separate bytecode Frame, which should -// follow EntryOptional and its LoadConstant instructions. -// -// - LoadConstant rA, D -// -// Used in conjunction with EntryOptional instruction to describe names and -// default values of optional parameters. -// -// - Frame D -// -// Reserve and initialize with null space for D local variables. -// -// - CheckFunctionTypeArgs A, D -// -// Check for a passed-in type argument vector of length A and -// store it at FP[D]. -// -// - CheckStack A -// -// Compare SP against isolate stack limit and call StackOverflow handler if -// necessary. Should be used in prologue (A = 0), or at the beginning of -// a loop with depth A. -// -// - Allocate D -// -// Allocate object of class PP[D] with no type arguments. -// -// - AllocateT -// -// Allocate object of class SP[0] with type arguments SP[-1]. -// -// - CreateArrayTOS -// -// Allocate array of length SP[0] with type arguments SP[-1]. -// -// - AllocateContext A, D -// -// Allocate Context object holding D context variables. -// A is a static ID of the context. Static ID of a context may be used to -// disambiguate accesses to different context objects. -// Context objects with the same ID should have the same number of -// context variables. -// -// - CloneContext A, D -// -// Clone Context object SP[0] holding D context variables. -// A is a static ID of the context. Cloned context has the same ID. -// -// - LoadContextParent -// -// Load parent from context SP[0]. -// -// - StoreContextParent -// -// Store context SP[0] into `parent` field of context SP[-1]. -// -// - LoadContextVar A, D -// -// Load value from context SP[0] at index D. -// A is a static ID of the context. -// -// - StoreContextVar A, D -// -// Store value SP[0] into context SP[-1] at index D. -// A is a static ID of the context. -// -// - PushConstant D -// -// Push value at index D from constant pool onto the stack. -// -// - PushNull -// -// Push `null` onto the stack. -// -// - PushTrue -// -// Push `true` onto the stack. -// -// - PushFalse -// -// Push `false` onto the stack. -// -// - PushInt rX -// -// Push int rX onto the stack. -// -// - Drop1 -// -// Drop 1 value from the stack -// -// - Push rX -// -// Push FP[rX] to the stack. -// -// - StoreLocal rX; PopLocal rX -// -// Store top of the stack into FP[rX] and pop it if needed. -// -// - LoadFieldTOS D -// -// Push value at offset (in words) PP[D] from object SP[0]. -// -// - StoreFieldTOS D -// -// Store value SP[0] into object SP[-1] at offset (in words) PP[D]. -// -// - StoreIndexedTOS -// -// Store SP[0] into array SP[-2] at index SP[-1]. No typechecking is done. -// SP[-2] is assumed to be a RawArray, SP[-1] to be a smi. -// -// - PushStatic D -// -// Pushes value of the static field PP[D] on to the stack. -// -// - StoreStaticTOS D -// -// Stores TOS into the static field PP[D]. -// -// - Jump target -// -// Jump to the given target. Target is specified as offset from the PC of the -// jump instruction. -// -// - JumpIfNoAsserts target -// -// Jump to the given target if assertions are not enabled. -// Target is specified as offset from the PC of the jump instruction. -// -// - JumpIfNotZeroTypeArgs target -// -// Jump to the given target if number of passed function type -// arguments is not zero. -// Target is specified as offset from the PC of the jump instruction. -// -// - JumpIfEqStrict target; JumpIfNeStrict target -// -// Jump to the given target if SP[-1] is the same (JumpIfEqStrict) / -// not the same (JumpIfNeStrict) object as SP[0]. -// -// - JumpIfTrue target; JumpIfFalse target -// - JumpIfNull target; JumpIfNotNull target -// -// Jump to the given target if SP[0] is true/false/null/not null. -// -// - IndirectStaticCall ArgC, D -// -// Invoke the function given by the ICData in SP[0] with arguments -// SP[-(1+ArgC)], ..., SP[-1] and argument descriptor PP[D], which -// indicates whether the first argument is a type argument vector. -// -// - DirectCall ArgC, D -// -// Invoke the function PP[D] with arguments -// SP[-(ArgC-1)], ..., SP[0] and argument descriptor PP[D+1]. -// -// - InterfaceCall ArgC, D -// -// Lookup and invoke method using ICData in PP[D] -// with arguments SP[-(1+ArgC)], ..., SP[-1]. -// Method has to be declared (explicitly or implicitly) in an interface -// implemented by a receiver, and passed arguments are valid for the -// interface method declaration. -// The ICData indicates whether the first argument is a type argument vector. -// -// - UncheckedInterfaceCall ArgC, D -// -// Same as InterfaceCall, but can omit type checks of generic-covariant -// parameters. -// -// - DynamicCall ArgC, D -// -// Lookup and invoke method using ICData in PP[D] -// with arguments SP[-(1+ArgC)], ..., SP[-1]. -// The ICData indicates whether the first argument is a type argument vector. -// -// - NativeCall D -// -// Invoke native function described by array at pool[D]. -// array[0] is wrapper, array[1] is function, array[2] is argc_tag. -// -// - ReturnTOS -// -// Return to the caller using a value from the top-of-stack as a result. -// -// Note: return instruction knows how many arguments to remove from the -// stack because it can look at the call instruction at caller's PC and -// take argument count from it. -// -// - AssertAssignable A, D -// -// Assert that instance SP[-4] is assignable to variable named SP[0] of -// type SP[-1] with instantiator type arguments SP[-3] and function type -// arguments SP[-2] using SubtypeTestCache PP[D]. -// If A is 1, then the instance may be a Smi. -// -// Instance remains on stack. Other arguments are consumed. -// -// - AssertBoolean A -// -// Assert that TOS is a boolean (A = 1) or that TOS is not null (A = 0). -// -// - AssertSubtype -// -// Assert that one type is a subtype of another. Throws a TypeError -// otherwise. The stack has the following arguments on it: -// -// SP[-4] instantiator type args -// SP[-3] function type args -// SP[-2] sub_type -// SP[-1] super_type -// SP[-0] dst_name -// -// All 5 arguments are consumed from the stack and no results is pushed. -// -// - LoadTypeArgumentsField D -// -// Load instantiator type arguments from an instance SP[0]. -// PP[D] = offset (in words) of type arguments field corresponding -// to an instance's class. -// -// - InstantiateType D -// -// Instantiate type PP[D] with instantiator type arguments SP[-1] and -// function type arguments SP[0]. -// -// - InstantiateTypeArgumentsTOS A, D -// -// Instantiate type arguments PP[D] with instantiator type arguments SP[-1] -// and function type arguments SP[0]. A != 0 indicates that resulting type -// arguments are all dynamic if both instantiator and function type -// arguments are all dynamic. -// -// - Throw A -// -// Throw (Rethrow if A != 0) exception. Exception object and stack object -// are taken from TOS. -// -// - MoveSpecial A, rX -// -// Copy value from special variable to FP[rX]. Currently only -// used to pass exception object (A = 0) and stack trace object (A = 1) to -// catch handler. -// -// - SetFrame A -// -// Reinitialize SP assuming that current frame has size A. -// Used to drop temporaries from the stack in the exception handler. -// -// - BooleanNegateTOS -// -// SP[0] = !SP[0] -// -// - EqualsNull -// -// SP[0] = (SP[0] == null) ? true : false -// -// - NegateInt -// -// Equivalent to invocation of unary int operator-. -// Receiver should have static type int. -// Check SP[0] for null; SP[0] = -SP[0]. -// -// - AddInt; SubInt; MulInt; TruncDivInt; ModInt; BitAndInt; BitOrInt; -// BitXorInt; ShlInt; ShrInt -// -// Equivalent to invocation of binary int operator +, -, *, ~/, %, &, |, -// ^, << or >>. Receiver and argument should have static type int. -// Check SP[-1] and SP[0] for null; push SP[-1] SP[0]. -// -// - CompareIntEq; CompareIntGt; CompareIntLt; CompareIntGe; CompareIntLe -// -// Equivalent to invocation of binary int operator ==, >, <, >= or <=. -// Receiver and argument should have static type int. -// Check SP[-1] and SP[0] for null; push SP[-1] SP[0] ? true : false. -// -// - NegateDouble -// -// Equivalent to invocation of unary double operator-. -// Receiver should have static type double. -// Check SP[0] for null; SP[0] = -SP[0]. -// -// - AddDouble; SubDouble; MulDouble; DivDouble -// -// Equivalent to invocation of binary int operator +, -, *, /. -// Receiver and argument should have static type double. -// Check SP[-1] and SP[0] for null; push SP[-1] SP[0]. -// -// - CompareDoubleEq; CompareDoubleGt; CompareDoubleLt; CompareDoubleGe; -// CompareDoubleLe -// -// Equivalent to invocation of binary double operator ==, >, <, >= or <=. -// Receiver and argument should have static type double. -// Check SP[-1] and SP[0] for null; push SP[-1] SP[0] ? true : false. -// -// - AllocateClosure D -// -// Allocate closure object for closure function ConstantPool[D]. -// -// BYTECODE LIST FORMAT -// -// KernelBytecode list below is specified using the following format: -// -// V(BytecodeName, OperandForm, BytecodeKind, Op1, Op2, Op3) -// -// - OperandForm specifies operand encoding and should be one of 0, A, D, X, T, -// A_E, A_Y, D_F or A_B_C (see ENCODING section above). -// -// - BytecodeKind is one of WIDE, RESV (reserved), ORDN (ordinary) -// -// - Op1, Op2, Op3 specify operand meaning. Possible values: -// -// ___ ignored / non-existent operand -// num immediate operand -// lit constant literal from object pool -// reg register (unsigned FP relative local) -// xeg x-register (signed FP relative local) -// tgt jump target relative to the PC of the current instruction -// -// TODO(vegorov) jump targets should be encoded relative to PC of the next -// instruction because PC is incremented immediately after fetch -// and before decoding. -// -#define PUBLIC_KERNEL_BYTECODES_LIST(V) \ - V(UnusedOpcode000, 0, RESV, ___, ___, ___) \ - V(UnusedOpcode001, 0, RESV, ___, ___, ___) \ - V(UnusedOpcode002, 0, RESV, ___, ___, ___) \ - V(UnusedOpcode003, 0, RESV, ___, ___, ___) \ - V(UnusedOpcode004, 0, RESV, ___, ___, ___) \ - V(UnusedOpcode005, 0, RESV, ___, ___, ___) \ - V(UnusedOpcode006, 0, RESV, ___, ___, ___) \ - V(UnusedOpcode007, 0, RESV, ___, ___, ___) \ - V(UnusedOpcode008, 0, RESV, ___, ___, ___) \ - V(UnusedOpcode009, 0, RESV, ___, ___, ___) \ - V(UnusedOpcode010, 0, RESV, ___, ___, ___) \ - V(UnusedOpcode011, 0, RESV, ___, ___, ___) \ - V(UnusedOpcode012, 0, RESV, ___, ___, ___) \ - V(UnusedOpcode013, 0, RESV, ___, ___, ___) \ - V(UnusedOpcode014, 0, RESV, ___, ___, ___) \ - V(UnusedOpcode015, 0, RESV, ___, ___, ___) \ - V(UnusedOpcode016, 0, RESV, ___, ___, ___) \ - V(UnusedOpcode017, 0, RESV, ___, ___, ___) \ - V(UnusedOpcode018, 0, RESV, ___, ___, ___) \ - V(UnusedOpcode019, 0, RESV, ___, ___, ___) \ - V(UnusedOpcode020, 0, RESV, ___, ___, ___) \ - V(UnusedOpcode021, 0, RESV, ___, ___, ___) \ - V(UnusedOpcode022, 0, RESV, ___, ___, ___) \ - V(UnusedOpcode023, 0, RESV, ___, ___, ___) \ - V(UnusedOpcode024, 0, RESV, ___, ___, ___) \ - V(UnusedOpcode025, 0, RESV, ___, ___, ___) \ - V(UnusedOpcode026, 0, RESV, ___, ___, ___) \ - V(UnusedOpcode027, 0, RESV, ___, ___, ___) \ - V(UnusedOpcode028, 0, RESV, ___, ___, ___) \ - V(UnusedOpcode029, 0, RESV, ___, ___, ___) \ - V(UnusedOpcode030, 0, RESV, ___, ___, ___) \ - V(UnusedOpcode031, 0, RESV, ___, ___, ___) \ - V(UnusedOpcode032, 0, RESV, ___, ___, ___) \ - V(UnusedOpcode033, 0, RESV, ___, ___, ___) \ - V(UnusedOpcode034, 0, RESV, ___, ___, ___) \ - V(UnusedOpcode035, 0, RESV, ___, ___, ___) \ - V(UnusedOpcode036, 0, RESV, ___, ___, ___) \ - V(UnusedOpcode037, 0, RESV, ___, ___, ___) \ - V(UnusedOpcode038, 0, RESV, ___, ___, ___) \ - V(UnusedOpcode039, 0, RESV, ___, ___, ___) \ - V(UnusedOpcode040, 0, RESV, ___, ___, ___) \ - V(UnusedOpcode041, 0, RESV, ___, ___, ___) \ - V(UnusedOpcode042, 0, RESV, ___, ___, ___) \ - V(UnusedOpcode043, 0, RESV, ___, ___, ___) \ - V(UnusedOpcode044, 0, RESV, ___, ___, ___) \ - V(UnusedOpcode045, 0, RESV, ___, ___, ___) \ - V(UnusedOpcode046, 0, RESV, ___, ___, ___) \ - V(UnusedOpcode047, 0, RESV, ___, ___, ___) \ - V(UnusedOpcode048, 0, RESV, ___, ___, ___) \ - V(UnusedOpcode049, 0, RESV, ___, ___, ___) \ - V(UnusedOpcode050, 0, RESV, ___, ___, ___) \ - V(UnusedOpcode051, 0, RESV, ___, ___, ___) \ - V(UnusedOpcode052, 0, RESV, ___, ___, ___) \ - V(UnusedOpcode053, 0, RESV, ___, ___, ___) \ - V(UnusedOpcode054, 0, RESV, ___, ___, ___) \ - V(UnusedOpcode055, 0, RESV, ___, ___, ___) \ - V(UnusedOpcode056, 0, RESV, ___, ___, ___) \ - V(UnusedOpcode057, 0, RESV, ___, ___, ___) \ - V(UnusedOpcode058, 0, RESV, ___, ___, ___) \ - V(UnusedOpcode059, 0, RESV, ___, ___, ___) \ - V(UnusedOpcode060, 0, RESV, ___, ___, ___) \ - V(UnusedOpcode061, 0, RESV, ___, ___, ___) \ - V(UnusedOpcode062, 0, RESV, ___, ___, ___) \ - V(UnusedOpcode063, 0, RESV, ___, ___, ___) \ - V(UnusedOpcode064, 0, RESV, ___, ___, ___) \ - V(UnusedOpcode065, 0, RESV, ___, ___, ___) \ - V(UnusedOpcode066, 0, RESV, ___, ___, ___) \ - V(UnusedOpcode067, 0, RESV, ___, ___, ___) \ - V(UnusedOpcode068, 0, RESV, ___, ___, ___) \ - V(UnusedOpcode069, 0, RESV, ___, ___, ___) \ - V(UnusedOpcode070, 0, RESV, ___, ___, ___) \ - V(UnusedOpcode071, 0, RESV, ___, ___, ___) \ - V(UnusedOpcode072, 0, RESV, ___, ___, ___) \ - V(UnusedOpcode073, 0, RESV, ___, ___, ___) \ - V(UnusedOpcode074, 0, RESV, ___, ___, ___) \ - V(UnusedOpcode075, 0, RESV, ___, ___, ___) \ - V(UnusedOpcode076, 0, RESV, ___, ___, ___) \ - V(UnusedOpcode077, 0, RESV, ___, ___, ___) \ - V(UnusedOpcode078, 0, RESV, ___, ___, ___) \ - V(UnusedOpcode079, 0, RESV, ___, ___, ___) \ - V(UnusedOpcode080, 0, RESV, ___, ___, ___) \ - V(UnusedOpcode081, 0, RESV, ___, ___, ___) \ - V(JumpIfInitialized, T, ORDN, tgt, ___, ___) \ - V(JumpIfInitialized_Wide, T, WIDE, tgt, ___, ___) \ - V(PushUninitializedSentinel, 0, ORDN, ___, ___, ___) \ - V(Trap, 0, ORDN, ___, ___, ___) \ - V(Entry, D, ORDN, num, ___, ___) \ - V(Entry_Wide, D, WIDE, num, ___, ___) \ - V(EntryFixed, A_E, ORDN, num, num, ___) \ - V(EntryFixed_Wide, A_E, WIDE, num, num, ___) \ - V(EntryOptional, A_B_C, ORDN, num, num, num) \ - V(Unused00, 0, RESV, ___, ___, ___) \ - V(LoadConstant, A_E, ORDN, reg, lit, ___) \ - V(LoadConstant_Wide, A_E, WIDE, reg, lit, ___) \ - V(Frame, D, ORDN, num, ___, ___) \ - V(Frame_Wide, D, WIDE, num, ___, ___) \ - V(CheckFunctionTypeArgs, A_E, ORDN, num, reg, ___) \ - V(CheckFunctionTypeArgs_Wide, A_E, WIDE, num, reg, ___) \ - V(CheckStack, A, ORDN, num, ___, ___) \ - V(DebugCheck, 0, ORDN, ___, ___, ___) \ - V(JumpIfUnchecked, T, ORDN, tgt, ___, ___) \ - V(JumpIfUnchecked_Wide, T, WIDE, tgt, ___, ___) \ - V(Allocate, D, ORDN, lit, ___, ___) \ - V(Allocate_Wide, D, WIDE, lit, ___, ___) \ - V(AllocateT, 0, ORDN, ___, ___, ___) \ - V(CreateArrayTOS, 0, ORDN, ___, ___, ___) \ - V(AllocateClosure, D, ORDN, lit, ___, ___) \ - V(AllocateClosure_Wide, D, WIDE, lit, ___, ___) \ - V(AllocateContext, A_E, ORDN, num, num, ___) \ - V(AllocateContext_Wide, A_E, WIDE, num, num, ___) \ - V(CloneContext, A_E, ORDN, num, num, ___) \ - V(CloneContext_Wide, A_E, WIDE, num, num, ___) \ - V(LoadContextParent, 0, ORDN, ___, ___, ___) \ - V(StoreContextParent, 0, ORDN, ___, ___, ___) \ - V(LoadContextVar, A_E, ORDN, num, num, ___) \ - V(LoadContextVar_Wide, A_E, WIDE, num, num, ___) \ - V(Unused04, 0, RESV, ___, ___, ___) \ - V(Unused05, 0, RESV, ___, ___, ___) \ - V(StoreContextVar, A_E, ORDN, num, num, ___) \ - V(StoreContextVar_Wide, A_E, WIDE, num, num, ___) \ - V(PushConstant, D, ORDN, lit, ___, ___) \ - V(PushConstant_Wide, D, WIDE, lit, ___, ___) \ - V(Unused06, 0, RESV, ___, ___, ___) \ - V(Unused07, 0, RESV, ___, ___, ___) \ - V(PushTrue, 0, ORDN, ___, ___, ___) \ - V(PushFalse, 0, ORDN, ___, ___, ___) \ - V(PushInt, X, ORDN, num, ___, ___) \ - V(PushInt_Wide, X, WIDE, num, ___, ___) \ - V(Unused08, 0, RESV, ___, ___, ___) \ - V(Unused09, 0, RESV, ___, ___, ___) \ - V(Unused10, 0, RESV, ___, ___, ___) \ - V(Unused11, 0, RESV, ___, ___, ___) \ - V(PushNull, 0, ORDN, ___, ___, ___) \ - V(Drop1, 0, ORDN, ___, ___, ___) \ - V(Push, X, ORDN, xeg, ___, ___) \ - V(Push_Wide, X, WIDE, xeg, ___, ___) \ - V(Unused12, 0, RESV, ___, ___, ___) \ - V(Unused13, 0, RESV, ___, ___, ___) \ - V(Unused14, 0, RESV, ___, ___, ___) \ - V(Unused15, 0, RESV, ___, ___, ___) \ - V(Unused16, 0, RESV, ___, ___, ___) \ - V(Unused17, 0, RESV, ___, ___, ___) \ - V(PopLocal, X, ORDN, xeg, ___, ___) \ - V(PopLocal_Wide, X, WIDE, xeg, ___, ___) \ - V(LoadStatic, D, ORDN, lit, ___, ___) \ - V(LoadStatic_Wide, D, WIDE, lit, ___, ___) \ - V(StoreLocal, X, ORDN, xeg, ___, ___) \ - V(StoreLocal_Wide, X, WIDE, xeg, ___, ___) \ - V(LoadFieldTOS, D, ORDN, lit, ___, ___) \ - V(LoadFieldTOS_Wide, D, WIDE, lit, ___, ___) \ - V(StoreFieldTOS, D, ORDN, lit, ___, ___) \ - V(StoreFieldTOS_Wide, D, WIDE, lit, ___, ___) \ - V(StoreIndexedTOS, 0, ORDN, ___, ___, ___) \ - V(Unused20, 0, RESV, ___, ___, ___) \ - V(InitLateField, D, ORDN, lit, ___, ___) \ - V(InitLateField_Wide, D, WIDE, lit, ___, ___) \ - V(StoreStaticTOS, D, ORDN, lit, ___, ___) \ - V(StoreStaticTOS_Wide, D, WIDE, lit, ___, ___) \ - V(Jump, T, ORDN, tgt, ___, ___) \ - V(Jump_Wide, T, WIDE, tgt, ___, ___) \ - V(JumpIfNoAsserts, T, ORDN, tgt, ___, ___) \ - V(JumpIfNoAsserts_Wide, T, WIDE, tgt, ___, ___) \ - V(JumpIfNotZeroTypeArgs, T, ORDN, tgt, ___, ___) \ - V(JumpIfNotZeroTypeArgs_Wide, T, WIDE, tgt, ___, ___) \ - V(JumpIfEqStrict, T, ORDN, tgt, ___, ___) \ - V(JumpIfEqStrict_Wide, T, WIDE, tgt, ___, ___) \ - V(JumpIfNeStrict, T, ORDN, tgt, ___, ___) \ - V(JumpIfNeStrict_Wide, T, WIDE, tgt, ___, ___) \ - V(JumpIfTrue, T, ORDN, tgt, ___, ___) \ - V(JumpIfTrue_Wide, T, WIDE, tgt, ___, ___) \ - V(JumpIfFalse, T, ORDN, tgt, ___, ___) \ - V(JumpIfFalse_Wide, T, WIDE, tgt, ___, ___) \ - V(JumpIfNull, T, ORDN, tgt, ___, ___) \ - V(JumpIfNull_Wide, T, WIDE, tgt, ___, ___) \ - V(JumpIfNotNull, T, ORDN, tgt, ___, ___) \ - V(JumpIfNotNull_Wide, T, WIDE, tgt, ___, ___) \ - V(DirectCall, D_F, ORDN, num, num, ___) \ - V(DirectCall_Wide, D_F, WIDE, num, num, ___) \ - V(UncheckedDirectCall, D_F, ORDN, num, num, ___) \ - V(UncheckedDirectCall_Wide, D_F, WIDE, num, num, ___) \ - V(InterfaceCall, D_F, ORDN, num, num, ___) \ - V(InterfaceCall_Wide, D_F, WIDE, num, num, ___) \ - V(Unused23, 0, RESV, ___, ___, ___) \ - V(Unused24, 0, RESV, ___, ___, ___) \ - V(InstantiatedInterfaceCall, D_F, ORDN, num, num, ___) \ - V(InstantiatedInterfaceCall_Wide, D_F, WIDE, num, num, ___) \ - V(UncheckedClosureCall, D_F, ORDN, num, num, ___) \ - V(UncheckedClosureCall_Wide, D_F, WIDE, num, num, ___) \ - V(UncheckedInterfaceCall, D_F, ORDN, num, num, ___) \ - V(UncheckedInterfaceCall_Wide, D_F, WIDE, num, num, ___) \ - V(DynamicCall, D_F, ORDN, num, num, ___) \ - V(DynamicCall_Wide, D_F, WIDE, num, num, ___) \ - V(NativeCall, D, ORDN, lit, ___, ___) \ - V(NativeCall_Wide, D, WIDE, lit, ___, ___) \ - V(ReturnTOS, 0, ORDN, ___, ___, ___) \ - V(Unused29, 0, RESV, ___, ___, ___) \ - V(AssertAssignable, A_E, ORDN, num, lit, ___) \ - V(AssertAssignable_Wide, A_E, WIDE, num, lit, ___) \ - V(Unused30, 0, RESV, ___, ___, ___) \ - V(Unused31, 0, RESV, ___, ___, ___) \ - V(AssertBoolean, A, ORDN, num, ___, ___) \ - V(AssertSubtype, 0, ORDN, ___, ___, ___) \ - V(LoadTypeArgumentsField, D, ORDN, lit, ___, ___) \ - V(LoadTypeArgumentsField_Wide, D, WIDE, lit, ___, ___) \ - V(InstantiateType, D, ORDN, lit, ___, ___) \ - V(InstantiateType_Wide, D, WIDE, lit, ___, ___) \ - V(InstantiateTypeArgumentsTOS, A_E, ORDN, num, lit, ___) \ - V(InstantiateTypeArgumentsTOS_Wide, A_E, WIDE, num, lit, ___) \ - V(Unused32, 0, RESV, ___, ___, ___) \ - V(Unused33, 0, RESV, ___, ___, ___) \ - V(Unused34, 0, RESV, ___, ___, ___) \ - V(Unused35, 0, RESV, ___, ___, ___) \ - V(Throw, A, ORDN, num, ___, ___) \ - V(SetFrame, A, ORDN, num, ___, num) \ - V(MoveSpecial, A_Y, ORDN, num, xeg, ___) \ - V(MoveSpecial_Wide, A_Y, WIDE, num, xeg, ___) \ - V(BooleanNegateTOS, 0, ORDN, ___, ___, ___) \ - V(EqualsNull, 0, ORDN, ___, ___, ___) \ - V(NullCheck, D, ORDN, lit, ___, ___) \ - V(NullCheck_Wide, D, WIDE, lit, ___, ___) \ - V(NegateInt, 0, ORDN, ___, ___, ___) \ - V(AddInt, 0, ORDN, ___, ___, ___) \ - V(SubInt, 0, ORDN, ___, ___, ___) \ - V(MulInt, 0, ORDN, ___, ___, ___) \ - V(TruncDivInt, 0, ORDN, ___, ___, ___) \ - V(ModInt, 0, ORDN, ___, ___, ___) \ - V(BitAndInt, 0, ORDN, ___, ___, ___) \ - V(BitOrInt, 0, ORDN, ___, ___, ___) \ - V(BitXorInt, 0, ORDN, ___, ___, ___) \ - V(ShlInt, 0, ORDN, ___, ___, ___) \ - V(ShrInt, 0, ORDN, ___, ___, ___) \ - V(CompareIntEq, 0, ORDN, ___, ___, ___) \ - V(CompareIntGt, 0, ORDN, ___, ___, ___) \ - V(CompareIntLt, 0, ORDN, ___, ___, ___) \ - V(CompareIntGe, 0, ORDN, ___, ___, ___) \ - V(CompareIntLe, 0, ORDN, ___, ___, ___) \ - V(NegateDouble, 0, ORDN, ___, ___, ___) \ - V(AddDouble, 0, ORDN, ___, ___, ___) \ - V(SubDouble, 0, ORDN, ___, ___, ___) \ - V(MulDouble, 0, ORDN, ___, ___, ___) \ - V(DivDouble, 0, ORDN, ___, ___, ___) \ - V(CompareDoubleEq, 0, ORDN, ___, ___, ___) \ - V(CompareDoubleGt, 0, ORDN, ___, ___, ___) \ - V(CompareDoubleLt, 0, ORDN, ___, ___, ___) \ - V(CompareDoubleGe, 0, ORDN, ___, ___, ___) \ - V(CompareDoubleLe, 0, ORDN, ___, ___, ___) \ - - // These bytecodes are only generated within the VM. Reassigning their - // opcodes is not a breaking change. -#define INTERNAL_KERNEL_BYTECODES_LIST(V) \ - V(VMInternal_ImplicitGetter, 0, ORDN, ___, ___, ___) \ - V(VMInternal_ImplicitSetter, 0, ORDN, ___, ___, ___) \ - V(VMInternal_ImplicitStaticGetter, 0, ORDN, ___, ___, ___) \ - V(VMInternal_MethodExtractor, 0, ORDN, ___, ___, ___) \ - V(VMInternal_InvokeClosure, 0, ORDN, ___, ___, ___) \ - V(VMInternal_InvokeField, 0, ORDN, ___, ___, ___) \ - V(VMInternal_ForwardDynamicInvocation, 0, ORDN, ___, ___, ___) \ - V(VMInternal_NoSuchMethodDispatcher, 0, ORDN, ___, ___, ___) \ - V(VMInternal_ImplicitStaticClosure, 0, ORDN, ___, ___, ___) \ - V(VMInternal_ImplicitInstanceClosure, 0, ORDN, ___, ___, ___) \ - -#define KERNEL_BYTECODES_LIST(V) \ - PUBLIC_KERNEL_BYTECODES_LIST(V) \ - INTERNAL_KERNEL_BYTECODES_LIST(V) - -// clang-format on - -typedef uint8_t KBCInstr; - -class KernelBytecode { - public: - // Magic value of bytecode files. - static const intptr_t kMagicValue = 0x44424332; // 'DBC2' - // Minimum bytecode format version supported by VM. - static const intptr_t kMinSupportedBytecodeFormatVersion = 28; - // Maximum bytecode format version supported by VM. - // The range of supported versions should include version produced by bytecode - // generator (currentBytecodeFormatVersion in pkg/vm/lib/bytecode/dbc.dart). - static const intptr_t kMaxSupportedBytecodeFormatVersion = 28; - - enum Opcode { -#define DECLARE_BYTECODE(name, encoding, kind, op1, op2, op3) k##name, - KERNEL_BYTECODES_LIST(DECLARE_BYTECODE) -#undef DECLARE_BYTECODE - }; - - static const char* NameOf(Opcode op) { - const char* names[] = { -#define NAME(name, encoding, kind, op1, op2, op3) #name, - KERNEL_BYTECODES_LIST(NAME) -#undef NAME - }; - return names[op]; - } - - static const intptr_t kInstructionSize[]; - - enum SpecialIndex { - kExceptionSpecialIndex, - kStackTraceSpecialIndex, - kSpecialIndexCount - }; - - private: - static const intptr_t kWideModifier = 1; - - // Should be used only on instructions with wide variants. - DART_FORCE_INLINE static bool IsWide(const KBCInstr* instr) { - return ((DecodeOpcode(instr) & kWideModifier) != 0); - } - - public: - DART_FORCE_INLINE static uint8_t DecodeA(const KBCInstr* bc) { return bc[1]; } - - DART_FORCE_INLINE static uint8_t DecodeB(const KBCInstr* bc) { return bc[2]; } - - DART_FORCE_INLINE static uint8_t DecodeC(const KBCInstr* bc) { return bc[3]; } - - DART_FORCE_INLINE static uint32_t DecodeD(const KBCInstr* bc) { - if (IsWide(bc)) { - return static_cast(bc[1]) | - (static_cast(bc[2]) << 8) | - (static_cast(bc[3]) << 16) | - (static_cast(bc[4]) << 24); - } else { - return bc[1]; - } - } - - DART_FORCE_INLINE static int32_t DecodeX(const KBCInstr* bc) { - if (IsWide(bc)) { - return static_cast(static_cast(bc[1]) | - (static_cast(bc[2]) << 8) | - (static_cast(bc[3]) << 16) | - (static_cast(bc[4]) << 24)); - } else { - return static_cast(bc[1]); - } - } - - DART_FORCE_INLINE static int32_t DecodeT(const KBCInstr* bc) { - if (IsWide(bc)) { - return static_cast((static_cast(bc[1]) << 8) | - (static_cast(bc[2]) << 16) | - (static_cast(bc[3]) << 24)) >> - 8; - } else { - return static_cast(bc[1]); - } - } - - DART_FORCE_INLINE static uint32_t DecodeE(const KBCInstr* bc) { - if (IsWide(bc)) { - return static_cast(bc[2]) | - (static_cast(bc[3]) << 8) | - (static_cast(bc[4]) << 16) | - (static_cast(bc[5]) << 24); - } else { - return bc[2]; - } - } - - DART_FORCE_INLINE static int32_t DecodeY(const KBCInstr* bc) { - if (IsWide(bc)) { - return static_cast(static_cast(bc[2]) | - (static_cast(bc[3]) << 8) | - (static_cast(bc[4]) << 16) | - (static_cast(bc[5]) << 24)); - } else { - return static_cast(bc[2]); - } - } - - DART_FORCE_INLINE static uint8_t DecodeF(const KBCInstr* bc) { - if (IsWide(bc)) { - return bc[5]; - } else { - return bc[2]; - } - } - - DART_FORCE_INLINE static Opcode DecodeOpcode(const KBCInstr* bc) { - return static_cast(bc[0]); - } - - DART_FORCE_INLINE static const KBCInstr* Next(const KBCInstr* bc) { - return bc + kInstructionSize[DecodeOpcode(bc)]; - } - - DART_FORCE_INLINE static uword Next(uword pc) { - return pc + kInstructionSize[DecodeOpcode( - reinterpret_cast(pc))]; - } - - DART_FORCE_INLINE static bool IsJumpOpcode(const KBCInstr* instr) { - switch (DecodeOpcode(instr)) { - case KernelBytecode::kJump: - case KernelBytecode::kJump_Wide: - case KernelBytecode::kJumpIfNoAsserts: - case KernelBytecode::kJumpIfNoAsserts_Wide: - case KernelBytecode::kJumpIfNotZeroTypeArgs: - case KernelBytecode::kJumpIfNotZeroTypeArgs_Wide: - case KernelBytecode::kJumpIfEqStrict: - case KernelBytecode::kJumpIfEqStrict_Wide: - case KernelBytecode::kJumpIfNeStrict: - case KernelBytecode::kJumpIfNeStrict_Wide: - case KernelBytecode::kJumpIfTrue: - case KernelBytecode::kJumpIfTrue_Wide: - case KernelBytecode::kJumpIfFalse: - case KernelBytecode::kJumpIfFalse_Wide: - case KernelBytecode::kJumpIfNull: - case KernelBytecode::kJumpIfNull_Wide: - case KernelBytecode::kJumpIfNotNull: - case KernelBytecode::kJumpIfNotNull_Wide: - case KernelBytecode::kJumpIfUnchecked: - case KernelBytecode::kJumpIfUnchecked_Wide: - case KernelBytecode::kJumpIfInitialized: - case KernelBytecode::kJumpIfInitialized_Wide: - return true; - - default: - return false; - } - } - - DART_FORCE_INLINE static bool IsJumpIfUncheckedOpcode(const KBCInstr* instr) { - switch (DecodeOpcode(instr)) { - case KernelBytecode::kJumpIfUnchecked: - case KernelBytecode::kJumpIfUnchecked_Wide: - return true; - default: - return false; - } - } - - DART_FORCE_INLINE static bool IsLoadConstantOpcode(const KBCInstr* instr) { - switch (DecodeOpcode(instr)) { - case KernelBytecode::kLoadConstant: - case KernelBytecode::kLoadConstant_Wide: - return true; - default: - return false; - } - } - - DART_FORCE_INLINE static bool IsCheckStackOpcode(const KBCInstr* instr) { - return DecodeOpcode(instr) == KernelBytecode::kCheckStack; - } - - DART_FORCE_INLINE static bool IsCheckFunctionTypeArgs(const KBCInstr* instr) { - switch (DecodeOpcode(instr)) { - case KernelBytecode::kCheckFunctionTypeArgs: - case KernelBytecode::kCheckFunctionTypeArgs_Wide: - return true; - default: - return false; - } - } - - DART_FORCE_INLINE static bool IsEntryOpcode(const KBCInstr* instr) { - switch (DecodeOpcode(instr)) { - case KernelBytecode::kEntry: - case KernelBytecode::kEntry_Wide: - return true; - default: - return false; - } - } - - DART_FORCE_INLINE static bool IsEntryFixedOpcode(const KBCInstr* instr) { - switch (DecodeOpcode(instr)) { - case KernelBytecode::kEntryFixed: - case KernelBytecode::kEntryFixed_Wide: - return true; - default: - return false; - } - } - - DART_FORCE_INLINE static bool IsEntryOptionalOpcode(const KBCInstr* instr) { - return DecodeOpcode(instr) == KernelBytecode::kEntryOptional; - } - - DART_FORCE_INLINE static bool IsFrameOpcode(const KBCInstr* instr) { - switch (DecodeOpcode(instr)) { - case KernelBytecode::kFrame: - case KernelBytecode::kFrame_Wide: - return true; - default: - return false; - } - } - - DART_FORCE_INLINE static bool IsSetFrameOpcode(const KBCInstr* instr) { - return DecodeOpcode(instr) == KernelBytecode::kSetFrame; - } - - DART_FORCE_INLINE static bool IsNativeCallOpcode(const KBCInstr* instr) { - switch (DecodeOpcode(instr)) { - case KernelBytecode::kNativeCall: - case KernelBytecode::kNativeCall_Wide: - return true; - default: - return false; - } - } - - DART_FORCE_INLINE static bool IsDebugCheckOpcode(const KBCInstr* instr) { - return DecodeOpcode(instr) == KernelBytecode::kDebugCheck; - } - - // The interpreter, the bytecode generator, the bytecode compiler, and this - // function must agree on this list of opcodes. - // For each instruction with listed opcode: - // - The interpreter checks for a debug break. - // - The bytecode generator emits a source position. - // - The bytecode compiler may emit a DebugStepCheck call. - DART_FORCE_INLINE static bool IsDebugCheckedOpcode(const KBCInstr* instr) { - switch (DecodeOpcode(instr)) { - case KernelBytecode::kDebugCheck: - case KernelBytecode::kDirectCall: - case KernelBytecode::kDirectCall_Wide: - case KernelBytecode::kUncheckedDirectCall: - case KernelBytecode::kUncheckedDirectCall_Wide: - case KernelBytecode::kInterfaceCall: - case KernelBytecode::kInterfaceCall_Wide: - case KernelBytecode::kInstantiatedInterfaceCall: - case KernelBytecode::kInstantiatedInterfaceCall_Wide: - case KernelBytecode::kUncheckedClosureCall: - case KernelBytecode::kUncheckedClosureCall_Wide: - case KernelBytecode::kUncheckedInterfaceCall: - case KernelBytecode::kUncheckedInterfaceCall_Wide: - case KernelBytecode::kDynamicCall: - case KernelBytecode::kDynamicCall_Wide: - case KernelBytecode::kReturnTOS: - case KernelBytecode::kEqualsNull: - case KernelBytecode::kNegateInt: - case KernelBytecode::kNegateDouble: - case KernelBytecode::kAddInt: - case KernelBytecode::kSubInt: - case KernelBytecode::kMulInt: - case KernelBytecode::kTruncDivInt: - case KernelBytecode::kModInt: - case KernelBytecode::kBitAndInt: - case KernelBytecode::kBitOrInt: - case KernelBytecode::kBitXorInt: - case KernelBytecode::kShlInt: - case KernelBytecode::kShrInt: - case KernelBytecode::kCompareIntEq: - case KernelBytecode::kCompareIntGt: - case KernelBytecode::kCompareIntLt: - case KernelBytecode::kCompareIntGe: - case KernelBytecode::kCompareIntLe: - case KernelBytecode::kAddDouble: - case KernelBytecode::kSubDouble: - case KernelBytecode::kMulDouble: - case KernelBytecode::kDivDouble: - case KernelBytecode::kCompareDoubleEq: - case KernelBytecode::kCompareDoubleGt: - case KernelBytecode::kCompareDoubleLt: - case KernelBytecode::kCompareDoubleGe: - case KernelBytecode::kCompareDoubleLe: - return true; - default: - return false; - } - } - - static const uint8_t kNativeCallToGrowableListArgc = 2; - - // Returns a fake return address which points after the 2-argument - // bytecode call, followed by ReturnTOS instructions. - static const KBCInstr* GetNativeCallToGrowableListReturnTrampoline(); - - DART_FORCE_INLINE static uint8_t DecodeArgc(const KBCInstr* ret_addr) { - // All call instructions have DF encoding, with argc being the last byte - // regardless of whether the wide variant is used or not. - return ret_addr[-1]; - } - - // Converts bytecode PC into an offset. - // For return addresses used in PcDescriptors, PC is also augmented by 1. - // TODO(regis): Eliminate this correction. - static intptr_t BytecodePcToOffset(uint32_t pc, bool is_return_address) { - return pc + (is_return_address ? 1 : 0); - } - - static uint32_t OffsetToBytecodePc(intptr_t offset, bool is_return_address) { - return offset - (is_return_address ? 1 : 0); - } - - static void GetVMInternalBytecodeInstructions(Opcode opcode, - const KBCInstr** instructions, - intptr_t* instructions_size); - - private: - DISALLOW_ALLOCATION(); - DISALLOW_IMPLICIT_CONSTRUCTORS(KernelBytecode); -}; - -} // namespace dart - -#endif // RUNTIME_VM_CONSTANTS_KBC_H_ diff --git a/runtime/vm/dart_entry.cc b/runtime/vm/dart_entry.cc index aec36e8793d..a17966f66b6 100644 --- a/runtime/vm/dart_entry.cc +++ b/runtime/vm/dart_entry.cc @@ -9,7 +9,6 @@ #include "vm/debugger.h" #include "vm/dispatch_table.h" #include "vm/heap/safepoint.h" -#include "vm/interpreter.h" #include "vm/object_store.h" #include "vm/resolver.h" #include "vm/runtime_entry.h" @@ -19,13 +18,11 @@ #include "vm/zone_text_buffer.h" #if !defined(DART_PRECOMPILED_RUNTIME) -#include "vm/compiler/frontend/bytecode_reader.h" #include "vm/compiler/jit/compiler.h" #endif // !defined(DART_PRECOMPILED_RUNTIME) namespace dart { -DECLARE_FLAG(bool, enable_interpreter); DECLARE_FLAG(bool, precompiled_mode); // A cache of VM heap allocated arguments descriptors. @@ -53,7 +50,6 @@ class ScopedIsolateStackLimits : public ValueObject { thread->SetStackLimit(Simulator::Current()->overflow_stack_limit()); #else thread->SetStackLimit(OSThread::Current()->overflow_stack_limit()); - // TODO(regis): For now, the interpreter is using its own stack limit. #endif #if defined(USING_SAFE_STACK) @@ -135,27 +131,6 @@ ObjectPtr DartEntry::InvokeFunction(const Function& function, ScopedIsolateStackLimits stack_limit(thread, current_sp); #if !defined(DART_PRECOMPILED_RUNTIME) if (!function.HasCode()) { - if (FLAG_enable_interpreter && function.IsBytecodeAllowed(zone)) { - if (!function.HasBytecode()) { - ErrorPtr error = - kernel::BytecodeReader::ReadFunctionBytecode(thread, function); - if (error != Error::null()) { - return error; - } - } - - // If we have bytecode but no native code then invoke the interpreter. - if (function.HasBytecode() && (FLAG_compilation_counter_threshold != 0)) { - ASSERT(thread->no_callback_scope_depth() == 0); - SuspendLongJumpScope suspend_long_jump_scope(thread); - TransitionToGenerated transition(thread); - return Interpreter::Current()->Call(function, arguments_descriptor, - arguments, thread); - } - - // Fall back to compilation. - } - const Object& result = Object::Handle(zone, Compiler::CompileFunction(thread, function)); if (result.IsError()) { diff --git a/runtime/vm/dart_entry.h b/runtime/vm/dart_entry.h index 4f81b2817f2..2ebdbe8f38d 100644 --- a/runtime/vm/dart_entry.h +++ b/runtime/vm/dart_entry.h @@ -174,8 +174,6 @@ class ArgumentsDescriptor : public ValueObject { friend class SnapshotWriter; friend class Serializer; friend class Deserializer; - friend class Interpreter; - friend class InterpreterHelpers; friend class Simulator; friend class SimulatorHelpers; DISALLOW_COPY_AND_ASSIGN(ArgumentsDescriptor); diff --git a/runtime/vm/debugger.cc b/runtime/vm/debugger.cc index feb43ae21a0..dfd6e56723b 100644 --- a/runtime/vm/debugger.cc +++ b/runtime/vm/debugger.cc @@ -10,12 +10,10 @@ #include "vm/code_patcher.h" #include "vm/compiler/api/deopt_id.h" #include "vm/compiler/assembler/disassembler.h" -#include "vm/compiler/assembler/disassembler_kbc.h" #include "vm/compiler/jit/compiler.h" #include "vm/dart_entry.h" #include "vm/flags.h" #include "vm/globals.h" -#include "vm/interpreter.h" #include "vm/isolate_reload.h" #include "vm/json_stream.h" #include "vm/kernel.h" @@ -40,7 +38,6 @@ #include "vm/visitor.h" #if !defined(DART_PRECOMPILED_RUNTIME) -#include "vm/compiler/frontend/bytecode_reader.h" #include "vm/deopt_instructions.h" #endif // !defined(DART_PRECOMPILED_RUNTIME) @@ -53,7 +50,6 @@ DEFINE_FLAG(bool, DEFINE_FLAG(bool, trace_rewind, false, "Trace frame rewind"); DEFINE_FLAG(bool, verbose_debug, false, "Verbose debugger messages"); -DECLARE_FLAG(bool, enable_interpreter); DECLARE_FLAG(bool, trace_deoptimization); DECLARE_FLAG(bool, warn_on_pause_with_no_debugger); @@ -74,7 +70,6 @@ BreakpointLocation::BreakpointLocation(const Script& script, requested_line_number_(requested_line_number), requested_column_number_(requested_column_number), function_(Function::null()), - bytecode_token_pos_(TokenPosition::kNoSource), code_token_pos_(TokenPosition::kNoSource) { ASSERT(!script.IsNull()); ASSERT(token_pos_.IsReal()); @@ -93,7 +88,6 @@ BreakpointLocation::BreakpointLocation(const String& url, requested_line_number_(requested_line_number), requested_column_number_(requested_column_number), function_(Function::null()), - bytecode_token_pos_(TokenPosition::kNoSource), code_token_pos_(TokenPosition::kNoSource) { ASSERT(requested_line_number_ >= 0); } @@ -111,8 +105,7 @@ bool BreakpointLocation::AnyEnabled() const { return breakpoints() != NULL; } -void BreakpointLocation::SetResolved(bool in_bytecode, - const Function& func, +void BreakpointLocation::SetResolved(const Function& func, TokenPosition token_pos) { ASSERT(!IsLatent()); ASSERT(func.script() == script_); @@ -122,14 +115,9 @@ void BreakpointLocation::SetResolved(bool in_bytecode, function_ = func.raw(); token_pos_ = token_pos; end_token_pos_ = token_pos; - if (in_bytecode) { - bytecode_token_pos_ = token_pos; - } else { - code_token_pos_ = token_pos; - } + code_token_pos_ = token_pos; } -// Returned resolved pos is either in code or in bytecode. void BreakpointLocation::GetCodeLocation(Script* script, TokenPosition* pos) const { if (IsLatent()) { @@ -182,7 +170,6 @@ void Breakpoint::PrintJSON(JSONStream* stream) { void CodeBreakpoint::VisitObjectPointers(ObjectPointerVisitor* visitor) { visitor->VisitPointer(reinterpret_cast(&code_)); - visitor->VisitPointer(reinterpret_cast(&bytecode_)); visitor->VisitPointer(reinterpret_cast(&saved_value_)); } @@ -198,7 +185,6 @@ ActivationFrame::ActivationFrame(uword pc, sp_(sp), ctx_(Context::ZoneHandle()), code_(Code::ZoneHandle(code.raw())), - bytecode_(Bytecode::ZoneHandle()), function_(Function::ZoneHandle(code.function())), live_frame_((kind == kRegular) || (kind == kAsyncActivation)), token_pos_initialized_(false), @@ -218,46 +204,12 @@ ActivationFrame::ActivationFrame(uword pc, ASSERT(!function_.IsNull()); } -#if !defined(DART_PRECOMPILED_RUNTIME) -ActivationFrame::ActivationFrame(uword pc, - uword fp, - uword sp, - const Bytecode& bytecode, - ActivationFrame::Kind kind) - : pc_(pc), - fp_(fp), - sp_(sp), - ctx_(Context::ZoneHandle()), - code_(Code::ZoneHandle()), - bytecode_(Bytecode::ZoneHandle(bytecode.raw())), - function_(Function::ZoneHandle(bytecode.function())), - live_frame_((kind == kRegular) || (kind == kAsyncActivation)), - token_pos_initialized_(false), - token_pos_(TokenPosition::kNoSource), - try_index_(-1), - deopt_id_(DeoptId::kNone), - line_number_(-1), - column_number_(-1), - context_level_(-1), - deopt_frame_(Array::ZoneHandle()), - deopt_frame_offset_(0), - kind_(kind), - vars_initialized_(false), - var_descriptors_(LocalVarDescriptors::ZoneHandle()), - desc_indices_(8), - pc_desc_(PcDescriptors::ZoneHandle()) { - // The frame of a bytecode stub has a null function. It may be encountered - // when single stepping. -} -#endif // !defined(DART_PRECOMPILED_RUNTIME) - ActivationFrame::ActivationFrame(Kind kind) : pc_(0), fp_(0), sp_(0), ctx_(Context::ZoneHandle()), code_(Code::ZoneHandle()), - bytecode_(Bytecode::ZoneHandle()), function_(Function::ZoneHandle()), live_frame_(kind == kRegular), token_pos_initialized_(false), @@ -281,7 +233,6 @@ ActivationFrame::ActivationFrame(const Closure& async_activation) sp_(0), ctx_(Context::ZoneHandle()), code_(Code::ZoneHandle()), - bytecode_(Bytecode::ZoneHandle()), function_(Function::ZoneHandle()), live_frame_(false), token_pos_initialized_(false), @@ -300,17 +251,10 @@ ActivationFrame::ActivationFrame(const Closure& async_activation) pc_desc_(PcDescriptors::ZoneHandle()) { // Extract the function and the code from the asynchronous activation. function_ = async_activation.function(); -#if !defined(DART_PRECOMPILED_RUNTIME) - if (!function_.HasCode() && function_.HasBytecode()) { - bytecode_ = function_.bytecode(); - } -#endif - if (bytecode_.IsNull()) { - // Force-optimize functions should not be debuggable. - ASSERT(!function_.ForceOptimize()); - function_.EnsureHasCompiledUnoptimizedCode(); - code_ = function_.unoptimized_code(); - } + // Force-optimize functions should not be debuggable. + ASSERT(!function_.ForceOptimize()); + function_.EnsureHasCompiledUnoptimizedCode(); + code_ = function_.unoptimized_code(); ctx_ = async_activation.context(); ASSERT(fp_ == 0); ASSERT(!ctx_.IsNull()); @@ -481,7 +425,7 @@ static bool IsImplicitFunction(const Function& func) { } bool Debugger::HasBreakpoint(const Function& func, Zone* zone) { - if (!func.HasCode() && !func.HasBytecode()) { + if (!func.HasCode()) { // If the function is not compiled yet, just check whether there // is a user-defined breakpoint that falls into the token // range of the function. This may be a false positive: the breakpoint @@ -553,58 +497,10 @@ void Debugger::PrintSettingsToJSONObject(JSONObject* jsobj) const { } } -// If the current top Dart frame is interpreted, returns the fp of the caller -// in compiled code that invoked the interpreter, or 0 if not found. -// If the current top Dart frame is compiled, returns the fp of the caller in -// interpreted bytecode that invoked compiled code, or ULONG_MAX if not found. -// Returning compiled code fp 0 (or bytecode fp ULONG_MAX) as fp value insures -// that the fp will compare as a callee of any valid frame pointer of the same -// mode (compiled code or bytecode). -static uword CrossCallerFp() { - StackFrameIterator iterator(ValidationPolicy::kDontValidateFrames, - Thread::Current(), - StackFrameIterator::kNoCrossThreadIteration); - StackFrame* frame; - do { - frame = iterator.NextFrame(); - RELEASE_ASSERT(frame != nullptr); - } while (!frame->IsDartFrame()); - const bool top_is_interpreted = frame->is_interpreted(); - do { - frame = iterator.NextFrame(); - if (frame == nullptr) { - return top_is_interpreted ? 0 : ULONG_MAX; - } - if (!frame->IsDartFrame()) { - continue; - } - } while (top_is_interpreted == frame->is_interpreted()); - return frame->fp(); -} - -ActivationFrame::Relation ActivationFrame::CompareTo( - uword other_fp, - bool other_is_interpreted) const { +ActivationFrame::Relation ActivationFrame::CompareTo(uword other_fp) const { if (fp() == other_fp) { - ASSERT(IsInterpreted() == other_is_interpreted); return kSelf; } - if (IsInterpreted()) { - if (!other_is_interpreted) { - // Instead of fp(), use the fp of the compiled frame that called into the - // interpreter (CrossCallerFp). - // Note that if CrossCallerFp == other_fp, it must compare as a caller. - return IsCalleeFrameOf(other_fp, CrossCallerFp()) ? kCallee : kCaller; - } - return IsBytecodeCalleeFrameOf(other_fp, fp()) ? kCallee : kCaller; - } - if (other_is_interpreted) { - // Instead of fp(), use the fp of the interpreted frame that called into - // compiled code (CrossCallerFp). - // Note that if CrossCallerFp == other_fp, it must compare as a caller. - return IsBytecodeCalleeFrameOf(other_fp, CrossCallerFp()) ? kCallee - : kCaller; - } return IsCalleeFrameOf(other_fp, fp()) ? kCallee : kCaller; } @@ -627,23 +523,17 @@ LibraryPtr ActivationFrame::Library() { } void ActivationFrame::GetPcDescriptors() { - ASSERT(!IsInterpreted()); // We need to set try_index_ simultaneously. if (pc_desc_.IsNull()) { pc_desc_ = code().pc_descriptors(); ASSERT(!pc_desc_.IsNull()); } } -// If not token_pos_initialized_, compute token_pos_, try_index_ and, -// if not IsInterpreted(), also compute deopt_id_. +// If not token_pos_initialized_, compute token_pos_, try_index_ and +// deopt_id_. TokenPosition ActivationFrame::TokenPos() { if (!token_pos_initialized_) { token_pos_initialized_ = true; - if (IsInterpreted()) { - token_pos_ = bytecode().GetTokenIndexOfPC(pc_); - try_index_ = bytecode().GetTryIndexAtPc(pc_); - return token_pos_; - } token_pos_ = TokenPosition::kNoSource; GetPcDescriptors(); PcDescriptors::Iterator iter(pc_desc_, PcDescriptorsLayout::kAnyKind); @@ -668,7 +558,6 @@ intptr_t ActivationFrame::TryIndex() { } intptr_t ActivationFrame::DeoptId() { - ASSERT(!IsInterpreted()); if (!token_pos_initialized_) { TokenPos(); // Side effect: computes token_pos_initialized_, try_index_. } @@ -701,11 +590,6 @@ intptr_t ActivationFrame::ColumnNumber() { void ActivationFrame::GetVarDescriptors() { if (var_descriptors_.IsNull()) { - if (IsInterpreted()) { - var_descriptors_ = bytecode().GetLocalVarDescriptors(); - ASSERT(!var_descriptors_.IsNull()); - return; - } Code& unoptimized_code = Code::Handle(function().unoptimized_code()); if (unoptimized_code.IsNull()) { Thread* thread = Thread::Current(); @@ -724,8 +608,8 @@ void ActivationFrame::GetVarDescriptors() { } bool ActivationFrame::IsDebuggable() const { - // When stepping in bytecode stub, function is null. - return !function().IsNull() && Debugger::IsDebuggable(function()); + ASSERT(!function().IsNull()); + return Debugger::IsDebuggable(function()); } void ActivationFrame::PrintDescriptorsError(const char* message) { @@ -735,14 +619,7 @@ void ActivationFrame::PrintDescriptorsError(const char* message) { OS::PrintErr("deopt_id_ %" Px "\n", deopt_id_); OS::PrintErr("context_level_ %" Px "\n", context_level_); OS::PrintErr("token_pos_ %s\n", token_pos_.ToCString()); - if (function().is_declared_in_bytecode()) { -#if !defined(DART_PRECOMPILED_RUNTIME) - KernelBytecodeDisassembler::Disassemble(function()); -#else - UNREACHABLE(); -#endif // !defined(DART_PRECOMPILED_RUNTIME) - } - if (!IsInterpreted()) { + { DisassembleToStdout formatter; code().Disassemble(&formatter); PcDescriptors::Handle(code().pc_descriptors()).Print(); @@ -763,63 +640,30 @@ intptr_t ActivationFrame::ContextLevel() { ASSERT(live_frame_); const Context& ctx = GetSavedCurrentContext(); if (context_level_ < 0 && !ctx.IsNull()) { - if (IsInterpreted()) { -#if !defined(DART_PRECOMPILED_RUNTIME) - Thread* thread = Thread::Current(); - Zone* zone = thread->zone(); - const auto& bytecode = Bytecode::Handle(zone, function_.bytecode()); - if (!bytecode.HasLocalVariablesInfo()) { - PrintDescriptorsError("Missing local variables info"); - } - intptr_t pc_offset = pc_ - bytecode.PayloadStart(); - // Look for innermost scope, i.e. with the highest context level. - // Since scopes are ordered by StartPC(), the last scope which includes - // pc_offset will be the innermost one. - kernel::BytecodeLocalVariablesIterator local_vars(zone, bytecode); - while (local_vars.MoveNext()) { - if (local_vars.Kind() == - kernel::BytecodeLocalVariablesIterator::kScope) { - if (local_vars.StartPC() > pc_offset) { - break; - } - if (pc_offset <= local_vars.EndPC()) { - ASSERT(context_level_ <= local_vars.ContextLevel()); - context_level_ = local_vars.ContextLevel(); - } - } - } - if (context_level_ < 0) { - PrintDescriptorsError("Missing context level in local variables info"); - } -#else - UNREACHABLE(); -#endif // !defined(DART_PRECOMPILED_RUNTIME) - } else { - ASSERT(!code_.is_optimized()); - GetVarDescriptors(); - intptr_t deopt_id = DeoptId(); - if (deopt_id == DeoptId::kNone) { - PrintDescriptorsError("Missing deopt id"); - } - intptr_t var_desc_len = var_descriptors_.Length(); - bool found = false; - for (intptr_t cur_idx = 0; cur_idx < var_desc_len; cur_idx++) { - LocalVarDescriptorsLayout::VarInfo var_info; - var_descriptors_.GetInfo(cur_idx, &var_info); - const int8_t kind = var_info.kind(); - if ((kind == LocalVarDescriptorsLayout::kContextLevel) && - (deopt_id >= var_info.begin_pos.value()) && - (deopt_id <= var_info.end_pos.value())) { - context_level_ = var_info.index(); - found = true; - break; - } - } - if (!found) { - PrintDescriptorsError("Missing context level in var descriptors"); - } - ASSERT(context_level_ >= 0); + ASSERT(!code_.is_optimized()); + GetVarDescriptors(); + intptr_t deopt_id = DeoptId(); + if (deopt_id == DeoptId::kNone) { + PrintDescriptorsError("Missing deopt id"); } + intptr_t var_desc_len = var_descriptors_.Length(); + bool found = false; + for (intptr_t cur_idx = 0; cur_idx < var_desc_len; cur_idx++) { + LocalVarDescriptorsLayout::VarInfo var_info; + var_descriptors_.GetInfo(cur_idx, &var_info); + const int8_t kind = var_info.kind(); + if ((kind == LocalVarDescriptorsLayout::kContextLevel) && + (deopt_id >= var_info.begin_pos.value()) && + (deopt_id <= var_info.end_pos.value())) { + context_level_ = var_info.index(); + found = true; + break; + } + } + if (!found) { + PrintDescriptorsError("Missing context level in var descriptors"); + } + ASSERT(context_level_ >= 0); } return context_level_; } @@ -845,13 +689,9 @@ ObjectPtr ActivationFrame::GetAsyncContextVariable(const String& name) { return GetStackVar(variable_index); } else { ASSERT(kind == LocalVarDescriptorsLayout::kContextVar); - // Variable descriptors constructed from bytecode have all variables of - // enclosing functions, even shadowed by the current function. - // Pick the variable with the highest context level. - if (var_info.scope_id > var_ctxt_level) { - var_ctxt_level = var_info.scope_id; - ctxt_slot = variable_index.value(); - } + var_ctxt_level = var_info.scope_id; + ctxt_slot = variable_index.value(); + break; } } } @@ -860,10 +700,7 @@ ObjectPtr ActivationFrame::GetAsyncContextVariable(const String& name) { ASSERT(!ctx_.IsNull()); // Compiled code uses relative context levels, i.e. the frame context // level is always 0 on entry. - // Bytecode uses absolute context levels, i.e. the frame context level - // on entry must be calculated. - const intptr_t frame_ctx_level = - function().is_declared_in_bytecode() ? ctx_.GetLevel() : 0; + const intptr_t frame_ctx_level = 0; return GetRelativeContextVar(var_ctxt_level, ctxt_slot, frame_ctx_level); } return GetContextVar(var_ctxt_level, ctxt_slot); @@ -883,8 +720,7 @@ ObjectPtr ActivationFrame::GetAsyncAwaiter( // Look up caller's closure on the stack. ObjectPtr* last_caller_obj = reinterpret_cast(GetCallerSp()); Closure& closure = Closure::Handle(); - closure = StackTraceUtils::FindClosureInFrame(last_caller_obj, function_, - IsInterpreted()); + closure = StackTraceUtils::FindClosureInFrame(last_caller_obj, function_); if (!closure.IsNull() && caller_closure_finder->IsRunningAsync(closure)) { closure = caller_closure_finder->FindCaller(closure); @@ -913,11 +749,7 @@ bool ActivationFrame::HandlesException(const Instance& exc_obj) { AbstractType& type = Type::Handle(); const bool is_async = function().IsAsyncClosure() || function().IsAsyncGenClosure(); - if (IsInterpreted()) { - handlers = bytecode().exception_handlers(); - } else { - handlers = code().exception_handlers(); - } + handlers = code().exception_handlers(); ASSERT(!handlers.IsNull()); intptr_t num_handlers_checked = 0; while (try_index != kInvalidTryIndex) { @@ -960,13 +792,9 @@ intptr_t ActivationFrame::GetAwaitJumpVariable() { if (var_descriptors_.GetName(i) == Symbols::AwaitJumpVar().raw()) { ASSERT(kind == LocalVarDescriptorsLayout::kContextVar); ASSERT(!ctx_.IsNull()); - // Variable descriptors constructed from bytecode have all variables of - // enclosing functions, even shadowed by the current function. - // Pick the :await_jump_var variable with the highest context level. - if (var_info.scope_id > var_ctxt_level) { - var_ctxt_level = var_info.scope_id; - ctxt_slot = var_info.index(); - } + var_ctxt_level = var_info.scope_id; + ctxt_slot = var_info.index(); + break; } } if (var_ctxt_level >= 0) { @@ -986,39 +814,6 @@ void ActivationFrame::ExtractTokenPositionFromAsyncClosure() { // This should only be called on frames that aren't active on the stack. ASSERT(fp() == 0); - if (function_.is_declared_in_bytecode()) { -#if !defined(DART_PRECOMPILED_RUNTIME) - const auto& bytecode = Bytecode::Handle(zone, function_.bytecode()); - if (!bytecode.HasSourcePositions()) { - return; - } - const intptr_t await_jump_var = GetAwaitJumpVariable(); - if (await_jump_var < 0) { - return; - } - // Yield points are counted from 1 (0 is reserved for normal entry). - intptr_t yield_point_index = 1; - kernel::BytecodeSourcePositionsIterator iter(zone, bytecode); - while (iter.MoveNext()) { - if (iter.IsYieldPoint()) { - if (yield_point_index == await_jump_var) { - token_pos_ = iter.TokenPos(); - token_pos_initialized_ = true; - const uword return_address = - KernelBytecode::Next(bytecode.PayloadStart() + iter.PcOffset()); - try_index_ = bytecode.GetTryIndexAtPc(return_address); - return; - } - ++yield_point_index; - } - } - return; -#else - UNREACHABLE(); -#endif // !defined(DART_PRECOMPILED_RUNTIME) - } - - ASSERT(!IsInterpreted()); const intptr_t await_jump_var = GetAwaitJumpVariable(); if (await_jump_var < 0) { return; @@ -1039,10 +834,7 @@ void ActivationFrame::ExtractTokenPositionFromAsyncClosure() { } bool ActivationFrame::IsAsyncMachinery() const { - if (function_.IsNull()) { - ASSERT(IsInterpreted()); // This frame is a bytecode stub frame. - return false; - } + ASSERT(!function_.IsNull()); Isolate* isolate = Isolate::Current(); if (function_.raw() == isolate->object_store()->complete_on_async_return()) { // We are completing an async function's completer. @@ -1201,17 +993,6 @@ ObjectPtr ActivationFrame::GetParameter(intptr_t index) { intptr_t num_parameters = function().num_fixed_parameters(); ASSERT(0 <= index && index < num_parameters); - if (IsInterpreted()) { - if (function().NumOptionalParameters() > 0) { - // Note that we do not access optional but only fixed parameters, hence - // we do not need to replicate the logic of IndexFor() in bytecode reader. - return GetVariableValue(fp() + index * kWordSize); - } else { - return GetVariableValue( - fp() - (kKBCParamEndSlotFromFp + num_parameters - index) * kWordSize); - } - } - if (function().NumOptionalParameters() > 0) { // If the function has optional parameters, the first positional parameter // can be in a number of places in the caller's frame depending on how many @@ -1232,13 +1013,6 @@ ObjectPtr ActivationFrame::GetClosure() { } ObjectPtr ActivationFrame::GetStackVar(VariableIndex variable_index) { - if (IsInterpreted()) { - intptr_t slot_index = -variable_index.value(); - if (slot_index < 0) { - slot_index -= kKBCParamEndSlotFromFp; // Accessing a parameter. - } - return GetVariableValue(fp() + slot_index * kWordSize); - } const intptr_t slot_index = runtime_frame_layout.FrameSlotForVariableIndex(variable_index.value()); if (deopt_frame_.IsNull()) { @@ -1540,7 +1314,7 @@ const char* ActivationFrame::ToCString() { const char* func_name = function().ToFullyQualifiedCString(); if (live_frame_) { return Thread::Current()->zone()->PrintToString( - "[ Frame pc(0x%" Px " %s offset:0x%" Px ") fp(0x%" Px ") sp(0x%" Px + "[ Frame pc(0x%" Px " code offset:0x%" Px ") fp(0x%" Px ") sp(0x%" Px ")\n" "\tfunction = %s\n" "\turl = %s\n" @@ -1548,20 +1322,16 @@ const char* ActivationFrame::ToCString() { "\n" "\tcontext = %s\n" "\tcontext level = %" Pd " ]\n", - pc(), IsInterpreted() ? "bytecode" : "code", - pc() - (IsInterpreted() ? bytecode().PayloadStart() - : code().PayloadStart()), - fp(), sp(), func_name, url.ToCString(), line, ctx_.ToCString(), - ContextLevel()); + pc(), pc() - code().PayloadStart(), fp(), sp(), func_name, + url.ToCString(), line, ctx_.ToCString(), ContextLevel()); } else { return Thread::Current()->zone()->PrintToString( - "[ Frame %s function = %s\n" + "[ Frame code function = %s\n" "\turl = %s\n" "\tline = %" Pd "\n" "\tcontext = %s]\n", - IsInterpreted() ? "bytecode" : "code", func_name, url.ToCString(), line, - ctx_.ToCString()); + func_name, url.ToCString(), line, ctx_.ToCString()); } } @@ -1584,11 +1354,7 @@ void ActivationFrame::PrintToJSONObjectRegular(JSONObject* jsobj) { const TokenPosition pos = TokenPos().SourcePosition(); jsobj->AddLocation(script, pos); jsobj->AddProperty("function", function()); - if (IsInterpreted()) { - jsobj->AddProperty("code", bytecode()); - } else { - jsobj->AddProperty("code", code()); - } + jsobj->AddProperty("code", code()); { JSONArray jsvars(jsobj, "vars"); const int num_vars = NumLocalVariables(); @@ -1624,11 +1390,7 @@ void ActivationFrame::PrintToJSONObjectAsyncCausal(JSONObject* jsobj) { const TokenPosition pos = TokenPos().SourcePosition(); jsobj->AddLocation(script, pos); jsobj->AddProperty("function", function()); - if (IsInterpreted()) { - jsobj->AddProperty("code", bytecode()); - } else { - jsobj->AddProperty("code", code()); - } + jsobj->AddProperty("code", code()); } void ActivationFrame::PrintToJSONObjectAsyncSuspensionMarker( @@ -1658,14 +1420,6 @@ void DebuggerStackTrace::AddAsyncCausalFrame(uword pc, const Code& code) { ActivationFrame::kAsyncCausal)); } -#if !defined(DART_PRECOMPILED_RUNTIME) -void DebuggerStackTrace::AddAsyncCausalFrame(uword pc, - const Bytecode& bytecode) { - trace_.Add( - new ActivationFrame(pc, 0, 0, bytecode, ActivationFrame::kAsyncCausal)); -} -#endif // !defined(DART_PRECOMPILED_RUNTIME) - const uint8_t kSafepointKind = PcDescriptorsLayout::kIcCall | PcDescriptorsLayout::kUnoptStaticCall | PcDescriptorsLayout::kRuntimeCall; @@ -1675,7 +1429,6 @@ CodeBreakpoint::CodeBreakpoint(const Code& code, uword pc, PcDescriptorsLayout::Kind kind) : code_(code.raw()), - bytecode_(Bytecode::null()), token_pos_(token_pos), pc_(pc), line_number_(-1), @@ -1690,32 +1443,12 @@ CodeBreakpoint::CodeBreakpoint(const Code& code, ASSERT((breakpoint_kind_ & kSafepointKind) != 0); } -CodeBreakpoint::CodeBreakpoint(const Bytecode& bytecode, - TokenPosition token_pos, - uword pc) - : code_(Code::null()), - bytecode_(bytecode.raw()), - token_pos_(token_pos), - pc_(pc), - line_number_(-1), - is_enabled_(false), - bpt_location_(NULL), - next_(NULL), - breakpoint_kind_(PcDescriptorsLayout::kAnyKind), - saved_value_(Code::null()) { - ASSERT(!bytecode.IsNull()); - ASSERT(FLAG_enable_interpreter); - ASSERT(token_pos_.IsReal()); - ASSERT(pc_ != 0); -} - CodeBreakpoint::~CodeBreakpoint() { // Make sure we don't leave patched code behind. ASSERT(!IsEnabled()); // Poison the data so we catch use after free errors. #ifdef DEBUG code_ = Code::null(); - bytecode_ = Bytecode::null(); pc_ = 0ul; bpt_location_ = NULL; next_ = NULL; @@ -1724,12 +1457,7 @@ CodeBreakpoint::~CodeBreakpoint() { } FunctionPtr CodeBreakpoint::function() const { - if (IsInterpreted()) { - ASSERT(Bytecode::Handle(bytecode_).function() != Function::null()); - return Bytecode::Handle(bytecode_).function(); - } else { - return Code::Handle(code_).function(); - } + return Code::Handle(code_).function(); } ScriptPtr CodeBreakpoint::SourceCode() { @@ -1753,30 +1481,14 @@ intptr_t CodeBreakpoint::LineNumber() { void CodeBreakpoint::Enable() { if (!is_enabled_) { - if (IsInterpreted()) { -#if !defined(DART_PRECOMPILED_RUNTIME) - SetBytecodeBreakpoint(); -#else - UNREACHABLE(); -#endif // !defined(DART_PRECOMPILED_RUNTIME) - } else { - PatchCode(); - } + PatchCode(); } ASSERT(is_enabled_); } void CodeBreakpoint::Disable() { if (is_enabled_) { - if (IsInterpreted()) { -#if !defined(DART_PRECOMPILED_RUNTIME) - UnsetBytecodeBreakpoint(); -#else - UNREACHABLE(); -#endif // !defined(DART_PRECOMPILED_RUNTIME) - } else { - RestoreCode(); - } + RestoreCode(); } ASSERT(!is_enabled_); } @@ -1796,11 +1508,9 @@ Debugger::Debugger(Isolate* isolate) async_causal_stack_trace_(NULL), awaiter_stack_trace_(NULL), stepping_fp_(0), - interpreted_stepping_(false), last_stepping_fp_(0), last_stepping_pos_(TokenPosition::kNoSource), async_stepping_fp_(0), - interpreted_async_stepping_(false), top_frame_awaiter_(Object::null()), skip_next_step_(false), needs_breakpoint_cleanup_(false), @@ -1994,14 +1704,6 @@ void Debugger::DeoptimizeWorld() { void Debugger::NotifySingleStepping(bool value) const { isolate_->set_single_step(value); -#if !defined(DART_PRECOMPILED_RUNTIME) - // Do not call Interpreter::Current(), which may allocate an interpreter. - Interpreter* interpreter = Thread::Current()->interpreter(); - if (interpreter != nullptr) { - // Do not reset is_debugging to false if bytecode debug breaks are enabled. - interpreter->set_is_debugging(value || HasEnabledBytecodeBreakpoints()); - } -#endif // !defined(DART_PRECOMPILED_RUNTIME) } ActivationFrame* Debugger::CollectDartFrame(Isolate* isolate, @@ -2024,22 +1726,6 @@ ActivationFrame* Debugger::CollectDartFrame(Isolate* isolate, } #if !defined(DART_PRECOMPILED_RUNTIME) -ActivationFrame* Debugger::CollectDartFrame(Isolate* isolate, - uword pc, - StackFrame* frame, - const Bytecode& bytecode, - ActivationFrame::Kind kind) { - ASSERT(bytecode.ContainsInstructionAt(pc)); - ActivationFrame* activation = - new ActivationFrame(pc, frame->fp(), frame->sp(), bytecode, kind); - if (FLAG_trace_debugger_stacktrace) { - const Context& ctx = activation->GetSavedCurrentContext(); - OS::PrintErr("\tUsing saved context: %s\n", ctx.ToCString()); - OS::PrintErr("\tLine number: %" Pd "\n", activation->LineNumber()); - } - return activation; -} - ArrayPtr Debugger::DeoptimizeToArray(Thread* thread, StackFrame* frame, const Code& code) { @@ -2072,9 +1758,6 @@ DebuggerStackTrace* Debugger::CollectStackTrace() { Thread::Current(), StackFrameIterator::kNoCrossThreadIteration); Code& code = Code::Handle(zone); -#if !defined(DART_PRECOMPILED_RUNTIME) - Bytecode& bytecode = Bytecode::Handle(zone); -#endif // !defined(DART_PRECOMPILED_RUNTIME) Code& inlined_code = Code::Handle(zone); Array& deopt_frame = Array::Handle(zone); @@ -2086,22 +1769,9 @@ DebuggerStackTrace* Debugger::CollectStackTrace() { frame->ToCString()); } if (frame->IsDartFrame()) { - if (frame->is_interpreted()) { -#if !defined(DART_PRECOMPILED_RUNTIME) - bytecode = frame->LookupDartBytecode(); - if (bytecode.function() == Function::null()) { - continue; // Skip bytecode stub frame. - } - stack_trace->AddActivation( - CollectDartFrame(isolate, frame->pc(), frame, bytecode)); -#else - UNREACHABLE(); -#endif // !defined(DART_PRECOMPILED_RUNTIME) - } else { - code = frame->LookupDartCode(); - AppendCodeFrames(thread, isolate, zone, stack_trace, frame, &code, - &inlined_code, &deopt_frame); - } + code = frame->LookupDartCode(); + AppendCodeFrames(thread, isolate, zone, stack_trace, frame, &code, + &inlined_code, &deopt_frame); } } return stack_trace; @@ -2164,9 +1834,6 @@ DebuggerStackTrace* Debugger::CollectAsyncCausalStackTrace() { Object& code_obj = Object::Handle(zone); Code& code = Code::Handle(zone); -#if !defined(DART_PRECOMPILED_RUNTIME) - Bytecode& bytecode = Bytecode::Handle(zone); -#endif // !defined(DART_PRECOMPILED_RUNTIME) Smi& offset = Smi::Handle(); Code& inlined_code = Code::Handle(zone); Array& deopt_frame = Array::Handle(zone); @@ -2200,22 +1867,9 @@ DebuggerStackTrace* Debugger::CollectAsyncCausalStackTrace() { while (synchronous_stack_trace_length > 0) { ASSERT(frame != NULL); if (frame->IsDartFrame()) { - if (frame->is_interpreted()) { -#if !defined(DART_PRECOMPILED_RUNTIME) - bytecode = frame->LookupDartBytecode(); - if (bytecode.function() == Function::null()) { - continue; // Skip bytecode stub frame. - } - stack_trace->AddActivation( - CollectDartFrame(isolate, frame->pc(), frame, bytecode)); -#else - UNREACHABLE(); -#endif // !defined(DART_PRECOMPILED_RUNTIME) - } else { - code = frame->LookupDartCode(); - AppendCodeFrames(thread, isolate, zone, stack_trace, frame, &code, - &inlined_code, &deopt_frame); - } + code = frame->LookupDartCode(); + AppendCodeFrames(thread, isolate, zone, stack_trace, frame, &code, + &inlined_code, &deopt_frame); synchronous_stack_trace_length--; } frame = iterator.NextFrame(); @@ -2241,14 +1895,6 @@ DebuggerStackTrace* Debugger::CollectAsyncCausalStackTrace() { i++; } else { offset = Smi::RawCast(async_stack_trace.PcOffsetAtFrame(i)); -#if !defined(DART_PRECOMPILED_RUNTIME) - if (code_obj.IsBytecode()) { - bytecode ^= code_obj.raw(); - uword pc = bytecode.PayloadStart() + offset.Value(); - stack_trace->AddAsyncCausalFrame(pc, bytecode); - continue; - } -#endif // !defined(DART_PRECOMPILED_RUNTIME) code ^= code_obj.raw(); uword pc = code.PayloadStart() + offset.Value(); if (code.is_optimized()) { @@ -2281,27 +1927,14 @@ DebuggerStackTrace* Debugger::CollectAsyncLazyStackTrace() { Code& inlined_code = Code::Handle(zone); Smi& offset = Smi::Handle(); Array& deopt_frame = Array::Handle(zone); -#if !defined(DART_PRECOMPILED_RUNTIME) - Bytecode& bytecode = Bytecode::Handle(zone); -#endif // !defined(DART_PRECOMPILED_RUNTIME) constexpr intptr_t kDefaultStackAllocation = 8; auto stack_trace = new DebuggerStackTrace(kDefaultStackAllocation); std::function on_sync_frame = [&](StackFrame* frame) { - if (frame->is_interpreted()) { -#if !defined(DART_PRECOMPILED_RUNTIME) - bytecode = frame->LookupDartBytecode(); - stack_trace->AddActivation( - CollectDartFrame(isolate, frame->pc(), frame, bytecode)); -#else - UNREACHABLE(); -#endif // !defined(DART_PRECOMPILED_RUNTIME) - } else { - code = frame->LookupDartCode(); - AppendCodeFrames(thread, isolate, zone, stack_trace, frame, &code, - &inlined_code, &deopt_frame); - } + code = frame->LookupDartCode(); + AppendCodeFrames(thread, isolate, zone, stack_trace, frame, &code, + &inlined_code, &deopt_frame); }; const auto& code_array = GrowableObjectArray::ZoneHandle( @@ -2353,7 +1986,6 @@ DebuggerStackTrace* Debugger::CollectAwaiterReturnStackTrace() { Object& code_object = Object::Handle(zone); Code& code = Code::Handle(zone); - Bytecode& bytecode = Bytecode::Handle(zone); Smi& offset = Smi::Handle(zone); Function& function = Function::Handle(zone); Code& inlined_code = Code::Handle(zone); @@ -2377,15 +2009,84 @@ DebuggerStackTrace* Debugger::CollectAwaiterReturnStackTrace() { frame->ToCString()); } if (frame->IsDartFrame()) { - if (frame->is_interpreted()) { - bytecode = frame->LookupDartBytecode(); - function = bytecode.function(); - if (function.IsNull()) { - continue; // Skip bytecode stub frame. + code = frame->LookupDartCode(); + if (code.is_optimized()) { + if (code.is_force_optimized()) { + if (FLAG_trace_debugger_stacktrace) { + function = code.function(); + ASSERT(!function.IsNull()); + OS::PrintErr( + "CollectAwaiterReturnStackTrace: " + "skipping force-optimized function: %s\n", + function.ToFullyQualifiedCString()); + } + // Skip frame of force-optimized (and non-debuggable) function. + continue; } + deopt_frame = DeoptimizeToArray(thread, frame, code); + bool found_async_awaiter = false; + bool abort_attempt_to_navigate_through_sync_async = false; + for (InlinedFunctionsIterator it(code, frame->pc()); !it.Done(); + it.Advance()) { + inlined_code = it.code(); + function = it.function(); + + if (skip_sync_async_frames_count > 0) { + function_name ^= function.QualifiedScrubbedName(); + if (!StackTraceUtils::CheckAndSkipAsync( + &skip_sync_async_frames_count, function_name)) { + // Unexpected function in sync async call + skip_sync_async_frames_count = -1; + abort_attempt_to_navigate_through_sync_async = true; + break; + } + } + + if (FLAG_trace_debugger_stacktrace) { + ASSERT(!function.IsNull()); + OS::PrintErr( + "CollectAwaiterReturnStackTrace: " + "visiting inlined function: %s\n ", + function.ToFullyQualifiedCString()); + } + intptr_t deopt_frame_offset = it.GetDeoptFpOffset(); + if (function.IsAsyncClosure() || function.IsAsyncGenClosure()) { + ActivationFrame* activation = CollectDartFrame( + isolate, it.pc(), frame, inlined_code, deopt_frame, + deopt_frame_offset, ActivationFrame::kAsyncActivation); + ASSERT(activation != NULL); + stack_trace->AddActivation(activation); + stack_has_async_function = true; + // Grab the awaiter. + async_activation ^= + activation->GetAsyncAwaiter(&caller_closure_finder); + found_async_awaiter = true; + // async function might have been called synchronously, in which + // case we need to keep going down the stack. + // To determine how we are called we peek few more frames further + // expecting to see Closure_call followed by + // AsyncAwaitCompleter_start. + // If we are able to see those functions we continue going down + // thestack, if we are not, we break out of the loop as we are + // not interested in exploring rest of the stack - there is only + // dart-internal code left. + skip_sync_async_frames_count = 2; + } else { + stack_trace->AddActivation( + CollectDartFrame(isolate, it.pc(), frame, inlined_code, + deopt_frame, deopt_frame_offset)); + } + } + // Break out of outer loop. + if (found_async_awaiter || + abort_attempt_to_navigate_through_sync_async) { + break; + } + } else { + function = code.function(); if (skip_sync_async_frames_count > 0) { - function_name = function.QualifiedScrubbedName(); + function_name ^= function.QualifiedScrubbedName(); if (!StackTraceUtils::CheckAndSkipAsync(&skip_sync_async_frames_count, function_name)) { // Unexpected function in synchronous call of async function. @@ -2394,9 +2095,9 @@ DebuggerStackTrace* Debugger::CollectAwaiterReturnStackTrace() { } if (function.IsAsyncClosure() || function.IsAsyncGenClosure()) { - ActivationFrame* activation = - CollectDartFrame(isolate, frame->pc(), frame, bytecode, - ActivationFrame::kAsyncActivation); + ActivationFrame* activation = CollectDartFrame( + isolate, frame->pc(), frame, code, Object::null_array(), 0, + ActivationFrame::kAsyncActivation); ASSERT(activation != NULL); stack_trace->AddActivation(activation); stack_has_async_function = true; @@ -2404,117 +2105,12 @@ DebuggerStackTrace* Debugger::CollectAwaiterReturnStackTrace() { async_activation ^= activation->GetAsyncAwaiter(&caller_closure_finder); async_stack_trace ^= activation->GetCausalStack(); - // Interpreted bytecode does not invoke _ClosureCall(). - // Skip _AsyncAwaitCompleterStart() only. - skip_sync_async_frames_count = 1; + // see comment regarding skipping frames of async functions called + // synchronously above. + skip_sync_async_frames_count = 2; } else { - stack_trace->AddActivation( - CollectDartFrame(isolate, frame->pc(), frame, bytecode)); - } - } else { - code = frame->LookupDartCode(); - if (code.is_optimized()) { - if (code.is_force_optimized()) { - if (FLAG_trace_debugger_stacktrace) { - function = code.function(); - ASSERT(!function.IsNull()); - OS::PrintErr( - "CollectAwaiterReturnStackTrace: " - "skipping force-optimized function: %s\n", - function.ToFullyQualifiedCString()); - } - // Skip frame of force-optimized (and non-debuggable) function. - continue; - } - deopt_frame = DeoptimizeToArray(thread, frame, code); - bool found_async_awaiter = false; - bool abort_attempt_to_navigate_through_sync_async = false; - for (InlinedFunctionsIterator it(code, frame->pc()); !it.Done(); - it.Advance()) { - inlined_code = it.code(); - function = it.function(); - - if (skip_sync_async_frames_count > 0) { - function_name ^= function.QualifiedScrubbedName(); - if (!StackTraceUtils::CheckAndSkipAsync( - &skip_sync_async_frames_count, function_name)) { - // Unexpected function in sync async call - skip_sync_async_frames_count = -1; - abort_attempt_to_navigate_through_sync_async = true; - break; - } - } - - if (FLAG_trace_debugger_stacktrace) { - ASSERT(!function.IsNull()); - OS::PrintErr( - "CollectAwaiterReturnStackTrace: " - "visiting inlined function: %s\n ", - function.ToFullyQualifiedCString()); - } - intptr_t deopt_frame_offset = it.GetDeoptFpOffset(); - if (function.IsAsyncClosure() || function.IsAsyncGenClosure()) { - ActivationFrame* activation = CollectDartFrame( - isolate, it.pc(), frame, inlined_code, deopt_frame, - deopt_frame_offset, ActivationFrame::kAsyncActivation); - ASSERT(activation != NULL); - stack_trace->AddActivation(activation); - stack_has_async_function = true; - // Grab the awaiter. - async_activation ^= - activation->GetAsyncAwaiter(&caller_closure_finder); - found_async_awaiter = true; - // async function might have been called synchronously, in which - // case we need to keep going down the stack. - // To determine how we are called we peek few more frames further - // expecting to see Closure_call followed by - // AsyncAwaitCompleter_start. - // If we are able to see those functions we continue going down - // thestack, if we are not, we break out of the loop as we are - // not interested in exploring rest of the stack - there is only - // dart-internal code left. - skip_sync_async_frames_count = 2; - } else { - stack_trace->AddActivation( - CollectDartFrame(isolate, it.pc(), frame, inlined_code, - deopt_frame, deopt_frame_offset)); - } - } - // Break out of outer loop. - if (found_async_awaiter || - abort_attempt_to_navigate_through_sync_async) { - break; - } - } else { - function = code.function(); - - if (skip_sync_async_frames_count > 0) { - function_name ^= function.QualifiedScrubbedName(); - if (!StackTraceUtils::CheckAndSkipAsync( - &skip_sync_async_frames_count, function_name)) { - // Unexpected function in synchronous call of async function. - break; - } - } - - if (function.IsAsyncClosure() || function.IsAsyncGenClosure()) { - ActivationFrame* activation = CollectDartFrame( - isolate, frame->pc(), frame, code, Object::null_array(), 0, - ActivationFrame::kAsyncActivation); - ASSERT(activation != NULL); - stack_trace->AddActivation(activation); - stack_has_async_function = true; - // Grab the awaiter. - async_activation ^= - activation->GetAsyncAwaiter(&caller_closure_finder); - async_stack_trace ^= activation->GetCausalStack(); - // see comment regarding skipping frames of async functions called - // synchronously above. - skip_sync_async_frames_count = 2; - } else { - stack_trace->AddActivation(CollectDartFrame( - isolate, frame->pc(), frame, code, Object::null_array(), 0)); - } + stack_trace->AddActivation(CollectDartFrame( + isolate, frame->pc(), frame, code, Object::null_array(), 0)); } } } @@ -2573,35 +2169,22 @@ DebuggerStackTrace* Debugger::CollectAwaiterReturnStackTrace() { } else { code_object = async_stack_trace.CodeAtFrame(i); offset = Smi::RawCast(async_stack_trace.PcOffsetAtFrame(i)); - if (code_object.IsBytecode()) { - bytecode ^= code_object.raw(); - if (FLAG_trace_debugger_stacktrace) { - OS::PrintErr("CollectAwaiterReturnStackTrace: visiting frame %" Pd - " in async causal stack trace:\n\t%s\n", - i, - Function::Handle(bytecode.function()) - .ToFullyQualifiedCString()); + code ^= code_object.raw(); + if (FLAG_trace_debugger_stacktrace) { + OS::PrintErr( + "CollectAwaiterReturnStackTrace: visiting frame %" Pd + " in async causal stack trace:\n\t%s\n", + i, Function::Handle(code.function()).ToFullyQualifiedCString()); + } + uword pc = code.PayloadStart() + offset.Value(); + if (code.is_optimized()) { + for (InlinedFunctionsIterator it(code, pc); !it.Done(); + it.Advance()) { + inlined_code = it.code(); + stack_trace->AddAsyncCausalFrame(it.pc(), inlined_code); } - uword pc = bytecode.PayloadStart() + offset.Value(); - stack_trace->AddAsyncCausalFrame(pc, bytecode); } else { - code ^= code_object.raw(); - if (FLAG_trace_debugger_stacktrace) { - OS::PrintErr( - "CollectAwaiterReturnStackTrace: visiting frame %" Pd - " in async causal stack trace:\n\t%s\n", - i, Function::Handle(code.function()).ToFullyQualifiedCString()); - } - uword pc = code.PayloadStart() + offset.Value(); - if (code.is_optimized()) { - for (InlinedFunctionsIterator it(code, pc); !it.Done(); - it.Advance()) { - inlined_code = it.code(); - stack_trace->AddAsyncCausalFrame(it.pc(), inlined_code); - } - } else { - stack_trace->AddAsyncCausalFrame(pc, code); - } + stack_trace->AddAsyncCausalFrame(pc, code); } } } @@ -2624,19 +2207,6 @@ ActivationFrame* Debugger::TopDartFrame() const { if (!frame->IsDartFrame()) { continue; } -#if !defined(DART_PRECOMPILED_RUNTIME) - if (frame->is_interpreted()) { - Bytecode& bytecode = Bytecode::Handle(frame->LookupDartBytecode()); - // Note that we do not skip bytecode stub frame (with a null function), - // so that we can ignore a single stepping breakpoint in such a frame. - // A bytecode stub contains a VM internal bytecode followed by a - // ReturnTOS bytecode. The single step on the ReturnTOS bytecode - // needs to be skipped. - ActivationFrame* activation = - new ActivationFrame(frame->pc(), frame->fp(), frame->sp(), bytecode); - return activation; - } -#endif // !defined(DART_PRECOMPILED_RUNTIME) Code& code = Code::Handle(frame->LookupDartCode()); ActivationFrame* activation = new ActivationFrame( frame->pc(), frame->fp(), frame->sp(), code, Object::null_array(), 0); @@ -2675,9 +2245,6 @@ DebuggerStackTrace* Debugger::StackTraceFrom(const class StackTrace& ex_trace) { Function& function = Function::Handle(); Object& code_object = Object::Handle(); Code& code = Code::Handle(); -#if !defined(DART_PRECOMPILED_RUNTIME) - Bytecode& bytecode = Bytecode::Handle(); -#endif // !defined(DART_PRECOMPILED_RUNTIME) const uword fp = 0; const uword sp = 0; @@ -2692,51 +2259,33 @@ DebuggerStackTrace* Debugger::StackTraceFrom(const class StackTrace& ex_trace) { // fewer frames that the pre-allocated trace (such as memory exhaustion with // a shallow stack). if (!code_object.IsNull()) { - if (code_object.IsBytecode()) { -#if !defined(DART_PRECOMPILED_RUNTIME) - bytecode ^= code_object.raw(); - function = bytecode.function(); - // Skip bytecode stub frames and frames with invisible function. - if (!function.IsNull() && function.is_visible()) { - ASSERT(function.raw() == bytecode.function()); - uword pc = - bytecode.PayloadStart() + Smi::Value(ex_trace.PcOffsetAtFrame(i)); - ActivationFrame* activation = - new ActivationFrame(pc, fp, sp, bytecode); - stack_trace->AddActivation(activation); - } -#else - UNREACHABLE(); -#endif // !defined(DART_PRECOMPILED_RUNTIME) - } else { - code ^= code_object.raw(); - ASSERT(code.IsFunctionCode()); - function = code.function(); - if (function.is_visible()) { - ASSERT(function.raw() == code.function()); - uword pc = - code.PayloadStart() + Smi::Value(ex_trace.PcOffsetAtFrame(i)); - if (code.is_optimized() && ex_trace.expand_inlined()) { - // Traverse inlined frames. - for (InlinedFunctionsIterator it(code, pc); !it.Done(); - it.Advance()) { - function = it.function(); - code = it.code(); - ASSERT(function.raw() == code.function()); - uword pc = it.pc(); - ASSERT(pc != 0); - ASSERT(code.PayloadStart() <= pc); - ASSERT(pc < (code.PayloadStart() + code.Size())); + code ^= code_object.raw(); + ASSERT(code.IsFunctionCode()); + function = code.function(); + if (function.is_visible()) { + ASSERT(function.raw() == code.function()); + uword pc = + code.PayloadStart() + Smi::Value(ex_trace.PcOffsetAtFrame(i)); + if (code.is_optimized() && ex_trace.expand_inlined()) { + // Traverse inlined frames. + for (InlinedFunctionsIterator it(code, pc); !it.Done(); + it.Advance()) { + function = it.function(); + code = it.code(); + ASSERT(function.raw() == code.function()); + uword pc = it.pc(); + ASSERT(pc != 0); + ASSERT(code.PayloadStart() <= pc); + ASSERT(pc < (code.PayloadStart() + code.Size())); - ActivationFrame* activation = new ActivationFrame( - pc, fp, sp, code, deopt_frame, deopt_frame_offset); - stack_trace->AddActivation(activation); - } - } else { ActivationFrame* activation = new ActivationFrame( pc, fp, sp, code, deopt_frame, deopt_frame_offset); stack_trace->AddActivation(activation); } + } else { + ActivationFrame* activation = new ActivationFrame( + pc, fp, sp, code, deopt_frame, deopt_frame_offset); + stack_trace->AddActivation(activation); } } } @@ -2915,8 +2464,7 @@ static void RefineBreakpointPos(const Script& script, // algorithm, which would be simpler. I believe that it only needs // two passes to support the recursive try-the-whole-function case. // Rewrite this later, once there are more tests in place. -TokenPosition Debugger::ResolveBreakpointPos(bool in_bytecode, - const Function& func, +TokenPosition Debugger::ResolveBreakpointPos(const Function& func, TokenPosition requested_token_pos, TokenPosition last_token_pos, intptr_t requested_column, @@ -2933,24 +2481,11 @@ TokenPosition Debugger::ResolveBreakpointPos(bool in_bytecode, Zone* zone = Thread::Current()->zone(); Script& script = Script::Handle(zone, func.script()); Code& code = Code::Handle(zone); -#if !defined(DART_PRECOMPILED_RUNTIME) - Bytecode& bytecode = Bytecode::Handle(zone); -#endif // !defined(DART_PRECOMPILED_RUNTIME) PcDescriptors& desc = PcDescriptors::Handle(zone); - if (in_bytecode) { -#if !defined(DART_PRECOMPILED_RUNTIME) - ASSERT(func.HasBytecode()); - bytecode = func.bytecode(); - ASSERT(!bytecode.IsNull()); -#else - UNREACHABLE(); -#endif // !defined(DART_PRECOMPILED_RUNTIME) - } else { - ASSERT(func.HasCode()); - code = func.unoptimized_code(); - ASSERT(!code.IsNull()); - desc = code.pc_descriptors(); - } + ASSERT(func.HasCode()); + code = func.unoptimized_code(); + ASSERT(!code.IsNull()); + desc = code.pc_descriptors(); // First pass: find the safe point which is closest to the beginning // of the given token range. @@ -2961,96 +2496,29 @@ TokenPosition Debugger::ResolveBreakpointPos(bool in_bytecode, // if column number is provided. TokenPosition best_token_pos = TokenPosition::kNoSource; - if (in_bytecode) { -#if !defined(DART_PRECOMPILED_RUNTIME) - kernel::BytecodeSourcePositionsIterator iter(zone, bytecode); - uword pc_offset = kUwordMax; - TokenPosition pos = TokenPosition::kNoSource; - // Ignore all possible breakpoint positions until the first DebugCheck - // opcode of the function. - const uword debug_check_pc = bytecode.GetFirstDebugCheckOpcodePc(); - if (debug_check_pc != 0) { - const uword debug_check_pc_offset = - debug_check_pc - bytecode.PayloadStart(); - while (iter.MoveNext()) { - if (pc_offset != kUwordMax) { - // Check that there is at least one 'debug checked' opcode in the last - // source position range. - uword pc = bytecode.GetDebugCheckedOpcodeReturnAddress( - pc_offset, iter.PcOffset()); - pc_offset = kUwordMax; - if (pc != 0) { - TokenPosition next_closest_token_position = - TokenPosition::kMaxSource; - if (requested_column >= 0) { - kernel::BytecodeSourcePositionsIterator iter2(zone, bytecode); - TokenPosition next_closest_token_position = - TokenPosition::kMaxSource; - while (iter2.MoveNext()) { - const TokenPosition next = iter2.TokenPos(); - if (next.IsReal() && next < next_closest_token_position && - next > pos) { - next_closest_token_position = next; - } - } - } - RefineBreakpointPos( - script, pos, next_closest_token_position, requested_token_pos, - last_token_pos, requested_column, exact_token_pos, - &best_fit_pos, &best_column, &best_line, &best_token_pos); - } - } - pos = iter.TokenPos(); - if ((!pos.IsReal()) || (pos < requested_token_pos) || - (pos > last_token_pos)) { - // Token is not in the target range. - continue; - } - pc_offset = iter.PcOffset(); - if (pc_offset < debug_check_pc_offset) { - // No breakpoints in prologue. - pc_offset = debug_check_pc_offset; - } - } - if (pc_offset != kUwordMax) { - uword pc = bytecode.GetDebugCheckedOpcodeReturnAddress(pc_offset, - bytecode.Size()); - if (pc != 0) { - RefineBreakpointPos(script, pos, TokenPosition::kMaxSource, - requested_token_pos, last_token_pos, - requested_column, exact_token_pos, &best_fit_pos, - &best_column, &best_line, &best_token_pos); + PcDescriptors::Iterator iter(desc, kSafepointKind); + while (iter.MoveNext()) { + const TokenPosition pos = iter.TokenPos(); + if ((!pos.IsReal()) || (pos < requested_token_pos) || + (pos > last_token_pos)) { + // Token is not in the target range. + continue; + } + TokenPosition next_closest_token_position = TokenPosition::kMaxSource; + if (requested_column >= 0) { + // Find next closest safepoint + PcDescriptors::Iterator iter2(desc, kSafepointKind); + while (iter2.MoveNext()) { + const TokenPosition next = iter2.TokenPos(); + if (next < next_closest_token_position && next > pos) { + next_closest_token_position = next; } } } -#else - UNREACHABLE(); -#endif // !defined(DART_PRECOMPILED_RUNTIME) - } else { - PcDescriptors::Iterator iter(desc, kSafepointKind); - while (iter.MoveNext()) { - const TokenPosition pos = iter.TokenPos(); - if ((!pos.IsReal()) || (pos < requested_token_pos) || - (pos > last_token_pos)) { - // Token is not in the target range. - continue; - } - TokenPosition next_closest_token_position = TokenPosition::kMaxSource; - if (requested_column >= 0) { - // Find next closest safepoint - PcDescriptors::Iterator iter2(desc, kSafepointKind); - while (iter2.MoveNext()) { - const TokenPosition next = iter2.TokenPos(); - if (next < next_closest_token_position && next > pos) { - next_closest_token_position = next; - } - } - } - RefineBreakpointPos(script, pos, next_closest_token_position, - requested_token_pos, last_token_pos, requested_column, - exact_token_pos, &best_fit_pos, &best_column, - &best_line, &best_token_pos); - } + RefineBreakpointPos(script, pos, next_closest_token_position, + requested_token_pos, last_token_pos, requested_column, + exact_token_pos, &best_fit_pos, &best_column, + &best_line, &best_token_pos); } // Second pass (if we found a safe point in the first pass). Find @@ -3072,51 +2540,24 @@ TokenPosition Debugger::ResolveBreakpointPos(bool in_bytecode, } uword lowest_pc_offset = kUwordMax; - if (in_bytecode) { -#if !defined(DART_PRECOMPILED_RUNTIME) - kernel::BytecodeSourcePositionsIterator iter(zone, bytecode); - while (iter.MoveNext()) { - const TokenPosition pos = iter.TokenPos(); - if (!pos.IsReal() || (pos < begin_pos) || (pos > end_of_line_pos)) { - // Token is not on same line as best fit. + PcDescriptors::Iterator iter(desc, kSafepointKind); + while (iter.MoveNext()) { + const TokenPosition pos = iter.TokenPos(); + if (!pos.IsReal() || (pos < begin_pos) || (pos > end_of_line_pos)) { + // Token is not on same line as best fit. + continue; + } + + if (requested_column >= 0) { + if (pos != best_token_pos) { continue; } - - if (requested_column >= 0) { - if (pos != best_token_pos) { - continue; - } - } - - // Prefer the lowest pc offset. - if (iter.PcOffset() < lowest_pc_offset) { - lowest_pc_offset = iter.PcOffset(); - best_fit_pos = pos; - } } -#else - UNREACHABLE(); -#endif // !defined(DART_PRECOMPILED_RUNTIME) - } else { - PcDescriptors::Iterator iter(desc, kSafepointKind); - while (iter.MoveNext()) { - const TokenPosition pos = iter.TokenPos(); - if (!pos.IsReal() || (pos < begin_pos) || (pos > end_of_line_pos)) { - // Token is not on same line as best fit. - continue; - } - if (requested_column >= 0) { - if (pos != best_token_pos) { - continue; - } - } - - // Prefer the lowest pc offset. - if (iter.PcOffset() < lowest_pc_offset) { - lowest_pc_offset = iter.PcOffset(); - best_fit_pos = pos; - } + // Prefer the lowest pc offset. + if (iter.PcOffset() < lowest_pc_offset) { + lowest_pc_offset = iter.PcOffset(); + best_fit_pos = pos; } } return best_fit_pos; @@ -3127,9 +2568,8 @@ TokenPosition Debugger::ResolveBreakpointPos(bool in_bytecode, // Since we have moved to the next line of the function, we no // longer are requesting a specific column number. if (last_token_pos < func.end_token_pos()) { - return ResolveBreakpointPos(in_bytecode, func, last_token_pos, - func.end_token_pos(), -1 /* no column */, - TokenPosition::kNoSource); + return ResolveBreakpointPos(func, last_token_pos, func.end_token_pos(), + -1 /* no column */, TokenPosition::kNoSource); } return TokenPosition::kNoSource; } @@ -3139,105 +2579,41 @@ void Debugger::MakeCodeBreakpointAt(const Function& func, ASSERT(loc->token_pos_.IsReal()); ASSERT((loc != NULL) && loc->IsResolved()); ASSERT(!func.HasOptimizedCode()); - ASSERT(func.HasCode() || func.HasBytecode()); -#if !defined(DART_PRECOMPILED_RUNTIME) - if (func.HasBytecode() && FLAG_enable_interpreter) { - Bytecode& bytecode = Bytecode::Handle(func.bytecode()); - ASSERT(!bytecode.IsNull()); - uword pc = 0; - if (bytecode.HasSourcePositions()) { - kernel::BytecodeSourcePositionsIterator iter(Thread::Current()->zone(), - bytecode); - // Ignore all possible breakpoint positions until the first DebugCheck - // opcode of the function. - const uword debug_check_pc = bytecode.GetFirstDebugCheckOpcodePc(); - if (debug_check_pc != 0) { - const uword debug_check_pc_offset = - debug_check_pc - bytecode.PayloadStart(); - uword pc_offset = kUwordMax; - while (iter.MoveNext()) { - if (pc_offset != kUwordMax) { - pc = bytecode.GetDebugCheckedOpcodeReturnAddress(pc_offset, - iter.PcOffset()); - pc_offset = kUwordMax; - if (pc != 0) { - // TODO(regis): We may want to find all PCs for a token position, - // e.g. in the case of duplicated bytecode in finally clauses. - break; - } - // This range does not contain a 'debug checked' opcode or the - // first DebugCheck opcode of the function is not reached yet. - } - if (iter.TokenPos() == loc->token_pos_) { - pc_offset = iter.PcOffset(); - if (pc_offset < debug_check_pc_offset) { - // No breakpoints in prologue. - pc_offset = debug_check_pc_offset; - } - } - } - if (pc_offset != kUwordMax) { - pc = bytecode.GetDebugCheckedOpcodeReturnAddress(pc_offset, - bytecode.Size()); - } - } - } - if (pc != 0) { - CodeBreakpoint* code_bpt = GetCodeBreakpoint(pc); - if (code_bpt == NULL) { - // No code breakpoint for this code exists; create one. - code_bpt = new CodeBreakpoint(bytecode, loc->token_pos_, pc); - if (FLAG_verbose_debug) { - OS::PrintErr("Setting bytecode breakpoint at pos %s pc %#" Px - " offset %#" Px "\n", - loc->token_pos_.ToCString(), pc, - pc - bytecode.PayloadStart()); - } - RegisterCodeBreakpoint(code_bpt); - } - code_bpt->set_bpt_location(loc); - if (loc->AnyEnabled()) { - code_bpt->Enable(); + ASSERT(func.HasCode()); + Code& code = Code::Handle(func.unoptimized_code()); + ASSERT(!code.IsNull()); + PcDescriptors& desc = PcDescriptors::Handle(code.pc_descriptors()); + uword lowest_pc_offset = kUwordMax; + PcDescriptorsLayout::Kind lowest_kind = PcDescriptorsLayout::kAnyKind; + // Find the safe point with the lowest compiled code address + // that maps to the token position of the source breakpoint. + PcDescriptors::Iterator iter(desc, kSafepointKind); + while (iter.MoveNext()) { + if (iter.TokenPos() == loc->token_pos_) { + if (iter.PcOffset() < lowest_pc_offset) { + lowest_pc_offset = iter.PcOffset(); + lowest_kind = iter.Kind(); } } } -#endif // !defined(DART_PRECOMPILED_RUNTIME) - if (func.HasCode()) { - Code& code = Code::Handle(func.unoptimized_code()); - ASSERT(!code.IsNull()); - PcDescriptors& desc = PcDescriptors::Handle(code.pc_descriptors()); - uword lowest_pc_offset = kUwordMax; - PcDescriptorsLayout::Kind lowest_kind = PcDescriptorsLayout::kAnyKind; - // Find the safe point with the lowest compiled code address - // that maps to the token position of the source breakpoint. - PcDescriptors::Iterator iter(desc, kSafepointKind); - while (iter.MoveNext()) { - if (iter.TokenPos() == loc->token_pos_) { - if (iter.PcOffset() < lowest_pc_offset) { - lowest_pc_offset = iter.PcOffset(); - lowest_kind = iter.Kind(); - } + if (lowest_pc_offset != kUwordMax) { + uword lowest_pc = code.PayloadStart() + lowest_pc_offset; + CodeBreakpoint* code_bpt = GetCodeBreakpoint(lowest_pc); + if (code_bpt == NULL) { + // No code breakpoint for this code exists; create one. + code_bpt = + new CodeBreakpoint(code, loc->token_pos_, lowest_pc, lowest_kind); + if (FLAG_verbose_debug) { + OS::PrintErr("Setting code breakpoint at pos %s pc %#" Px + " offset %#" Px "\n", + loc->token_pos_.ToCString(), lowest_pc, + lowest_pc - code.PayloadStart()); } + RegisterCodeBreakpoint(code_bpt); } - if (lowest_pc_offset != kUwordMax) { - uword lowest_pc = code.PayloadStart() + lowest_pc_offset; - CodeBreakpoint* code_bpt = GetCodeBreakpoint(lowest_pc); - if (code_bpt == NULL) { - // No code breakpoint for this code exists; create one. - code_bpt = - new CodeBreakpoint(code, loc->token_pos_, lowest_pc, lowest_kind); - if (FLAG_verbose_debug) { - OS::PrintErr("Setting code breakpoint at pos %s pc %#" Px - " offset %#" Px "\n", - loc->token_pos_.ToCString(), lowest_pc, - lowest_pc - code.PayloadStart()); - } - RegisterCodeBreakpoint(code_bpt); - } - code_bpt->set_bpt_location(loc); - if (loc->AnyEnabled()) { - code_bpt->Enable(); - } + code_bpt->set_bpt_location(loc); + if (loc->AnyEnabled()) { + code_bpt->Enable(); } } } @@ -3246,7 +2622,6 @@ void Debugger::FindCompiledFunctions( const Script& script, TokenPosition start_pos, TokenPosition end_pos, - GrowableObjectArray* bytecode_function_list, GrowableObjectArray* code_function_list) { Thread* thread = Thread::Current(); Zone* zone = thread->zone(); @@ -3264,9 +2639,6 @@ void Debugger::FindCompiledFunctions( (function.end_token_pos() == end_pos) && (function.script() == script.raw())) { if (function.is_debuggable()) { - if (FLAG_enable_interpreter && function.HasBytecode()) { - bytecode_function_list->Add(function); - } if (function.HasCode()) { code_function_list->Add(function); } @@ -3274,9 +2646,6 @@ void Debugger::FindCompiledFunctions( if (function.HasImplicitClosureFunction()) { function = function.ImplicitClosureFunction(); if (function.is_debuggable()) { - if (FLAG_enable_interpreter && function.HasBytecode()) { - bytecode_function_list->Add(function); - } if (function.HasCode()) { code_function_list->Add(function); } @@ -3310,29 +2679,17 @@ void Debugger::FindCompiledFunctions( function ^= functions.At(pos); ASSERT(!function.IsNull()); bool function_added = false; - if (function.is_debuggable() && - (function.HasCode() || - (FLAG_enable_interpreter && function.HasBytecode())) && + if (function.is_debuggable() && function.HasCode() && function.token_pos() == start_pos && function.end_token_pos() == end_pos && function.script() == script.raw()) { - if (FLAG_enable_interpreter && function.HasBytecode()) { - bytecode_function_list->Add(function); - } - if (function.HasCode()) { - code_function_list->Add(function); - } + code_function_list->Add(function); function_added = true; } if (function_added && function.HasImplicitClosureFunction()) { function = function.ImplicitClosureFunction(); - if (function.is_debuggable()) { - if (FLAG_enable_interpreter && function.HasBytecode()) { - bytecode_function_list->Add(function); - } - if (function.HasCode()) { - code_function_list->Add(function); - } + if (function.is_debuggable() && function.HasCode()) { + code_function_list->Add(function); } } } @@ -3498,8 +2855,6 @@ bool Debugger::FindBestFit(const Script& script, } BreakpointLocation* Debugger::SetCodeBreakpoints( - bool in_bytecode, - BreakpointLocation* loc, const Script& script, TokenPosition token_pos, TokenPosition last_token_pos, @@ -3507,24 +2862,18 @@ BreakpointLocation* Debugger::SetCodeBreakpoints( intptr_t requested_column, TokenPosition exact_token_pos, const GrowableObjectArray& functions) { - ASSERT(!in_bytecode || FLAG_enable_interpreter); Function& function = Function::Handle(); function ^= functions.At(0); - TokenPosition breakpoint_pos = - ResolveBreakpointPos(in_bytecode, function, token_pos, last_token_pos, - requested_column, exact_token_pos); + TokenPosition breakpoint_pos = ResolveBreakpointPos( + function, token_pos, last_token_pos, requested_column, exact_token_pos); if (!breakpoint_pos.IsReal()) { return NULL; } - if (loc == NULL) { - // Find an existing resolved breakpoint location. - loc = GetBreakpointLocation( - script, TokenPosition::kNoSource, - /* requested_line = */ -1, - /* requested_column = */ -1, - in_bytecode ? breakpoint_pos : TokenPosition::kNoSource, - !in_bytecode ? breakpoint_pos : TokenPosition::kNoSource); - } + // Find an existing resolved breakpoint location. + BreakpointLocation* loc = + GetBreakpointLocation(script, TokenPosition::kNoSource, + /* requested_line = */ -1, + /* requested_column = */ -1, breakpoint_pos); if (loc == NULL) { // Find an existing unresolved breakpoint location. loc = GetBreakpointLocation(script, token_pos, requested_line, @@ -3536,28 +2885,26 @@ BreakpointLocation* Debugger::SetCodeBreakpoints( RegisterBreakpointLocation(loc); } // A source breakpoint for this location may already exists, but it may - // not yet be resolved in both bytecode and code. - if (loc->IsResolved(in_bytecode)) { + // not yet be resolved in code. + if (loc->IsResolved()) { return loc; } - loc->SetResolved(in_bytecode, function, breakpoint_pos); + loc->SetResolved(function, breakpoint_pos); // Create code breakpoints for all compiled functions we found. Function& func = Function::Handle(); const intptr_t num_functions = functions.Length(); for (intptr_t i = 0; i < num_functions; i++) { func ^= functions.At(i); - ASSERT((in_bytecode && func.HasBytecode()) || - (!in_bytecode && func.HasCode())); + ASSERT(func.HasCode()); MakeCodeBreakpointAt(func, loc); } if (FLAG_verbose_debug) { intptr_t line_number; intptr_t column_number; script.GetTokenLocation(breakpoint_pos, &line_number, &column_number); - OS::PrintErr("Resolved %s breakpoint for function '%s' at line %" Pd + OS::PrintErr("Resolved code breakpoint for function '%s' at line %" Pd " col %" Pd "\n", - in_bytecode ? "bytecode" : "code", func.ToFullyQualifiedCString(), line_number, column_number); } return loc; @@ -3578,7 +2925,7 @@ BreakpointLocation* Debugger::SetBreakpoint(const Script& script, } else { func = function.raw(); if (!func.token_pos().IsReal()) { - return NULL; // Missing source positions in bytecode? + return NULL; // Missing source positions? } } if (!func.IsNull()) { @@ -3587,14 +2934,12 @@ BreakpointLocation* Debugger::SetBreakpoint(const Script& script, // there may be copies of mixin functions. Collect all compiled // functions whose source code range matches exactly the best fit // function we found. - GrowableObjectArray& bytecode_functions = - GrowableObjectArray::Handle(GrowableObjectArray::New()); GrowableObjectArray& code_functions = GrowableObjectArray::Handle(GrowableObjectArray::New()); FindCompiledFunctions(script, func.token_pos(), func.end_token_pos(), - &bytecode_functions, &code_functions); + &code_functions); - if (bytecode_functions.Length() > 0 || code_functions.Length() > 0) { + if (code_functions.Length() > 0) { // One or more function object containing this breakpoint location // have already been compiled. We can resolve the breakpoint now. // If requested_column is larger than zero, [token_pos, last_token_pos] @@ -3607,19 +2952,9 @@ BreakpointLocation* Debugger::SetBreakpoint(const Script& script, #endif // !defined(DART_PRECOMPILED_RUNTIME) } DeoptimizeWorld(); - // Since source positions may differ in code and bytecode, process - // breakpoints in bytecode and code separately. - BreakpointLocation* loc = NULL; - if (bytecode_functions.Length() > 0) { - loc = SetCodeBreakpoints(true, loc, script, token_pos, last_token_pos, - requested_line, requested_column, - exact_token_pos, bytecode_functions); - } - if (code_functions.Length() > 0) { - loc = SetCodeBreakpoints(false, loc, script, token_pos, last_token_pos, - requested_line, requested_column, - exact_token_pos, code_functions); - } + BreakpointLocation* loc = + SetCodeBreakpoints(script, token_pos, last_token_pos, requested_line, + requested_column, exact_token_pos, code_functions); if (loc != NULL) { return loc; } @@ -3955,7 +3290,6 @@ void Debugger::SetAsyncSteppingFramePointer(DebuggerStackTrace* stack_trace) { (stack_trace->FrameAt(0)->function().IsAsyncClosure() || stack_trace->FrameAt(0)->function().IsAsyncGenClosure())) { async_stepping_fp_ = stack_trace->FrameAt(0)->fp(); - interpreted_async_stepping_ = stack_trace->FrameAt(0)->IsInterpreted(); } else { async_stepping_fp_ = 0; } @@ -3964,7 +3298,6 @@ void Debugger::SetAsyncSteppingFramePointer(DebuggerStackTrace* stack_trace) { void Debugger::SetSyncSteppingFramePointer(DebuggerStackTrace* stack_trace) { if (stack_trace->Length() > 0) { stepping_fp_ = stack_trace->FrameAt(0)->fp(); - interpreted_stepping_ = stack_trace->FrameAt(0)->IsInterpreted(); } else { stepping_fp_ = 0; } @@ -4025,7 +3358,6 @@ void Debugger::HandleSteppingRequest(DebuggerStackTrace* stack_trace, ActivationFrame* frame = stack_trace->FrameAt(i); if (frame->IsDebuggable()) { stepping_fp_ = frame->fp(); - interpreted_stepping_ = frame->IsInterpreted(); break; } } @@ -4149,33 +3481,10 @@ static uword LookupRewindPc(const Code& code, uword return_address) { return 0; } -// Given a return address, find the "rewind" pc, which is the pc -// before the corresponding call. -static uword LookupRewindPc(const Bytecode& bytecode, uword return_address) { -#if defined(DART_PRECOMPILED_RUNTIME) - UNREACHABLE(); -#else - ASSERT(bytecode.ContainsInstructionAt(return_address)); - uword pc = bytecode.PayloadStart(); - const uword end_pc = pc + bytecode.Size(); - while (pc < end_pc) { - uword next_pc = KernelBytecode::Next(pc); - if (next_pc == return_address) { - return pc; - } - pc = next_pc; - } - return 0; -#endif -} - void Debugger::RewindToFrame(intptr_t frame_index) { Thread* thread = Thread::Current(); Zone* zone = thread->zone(); Code& code = Code::Handle(zone); -#if !defined(DART_PRECOMPILED_RUNTIME) - Bytecode& bytecode = Bytecode::Handle(zone); -#endif // !defined(DART_PRECOMPILED_RUNTIME) Function& function = Function::Handle(zone); // Find the requested frame. @@ -4187,47 +3496,29 @@ void Debugger::RewindToFrame(intptr_t frame_index) { frame = iterator.NextFrame()) { ASSERT(frame->IsValid()); if (frame->IsDartFrame()) { - if (frame->is_interpreted()) { -#if !defined(DART_PRECOMPILED_RUNTIME) - bytecode = frame->LookupDartBytecode(); - function = bytecode.function(); - if (function.IsNull() || !IsFunctionVisible(function)) { - continue; // Skip bytecode stub frame or invisible frame. - } - if (current_frame == frame_index) { - // We are rewinding to an interpreted frame. - RewindToInterpretedFrame(frame, bytecode); - UNREACHABLE(); - } - current_frame++; -#else - UNREACHABLE(); -#endif // !defined(DART_PRECOMPILED_RUNTIME) - } else { - code = frame->LookupDartCode(); - function = code.function(); - if (!IsFunctionVisible(function)) { - continue; - } - if (code.is_optimized()) { - intptr_t sub_index = 0; - for (InlinedFunctionsIterator it(code, frame->pc()); !it.Done(); - it.Advance()) { - if (current_frame == frame_index) { - RewindToOptimizedFrame(frame, code, sub_index); - UNREACHABLE(); - } - current_frame++; - sub_index++; - } - } else { + code = frame->LookupDartCode(); + function = code.function(); + if (!IsFunctionVisible(function)) { + continue; + } + if (code.is_optimized()) { + intptr_t sub_index = 0; + for (InlinedFunctionsIterator it(code, frame->pc()); !it.Done(); + it.Advance()) { if (current_frame == frame_index) { - // We are rewinding to an unoptimized frame. - RewindToUnoptimizedFrame(frame, code); + RewindToOptimizedFrame(frame, code, sub_index); UNREACHABLE(); } current_frame++; + sub_index++; } + } else { + if (current_frame == frame_index) { + // We are rewinding to an unoptimized frame. + RewindToUnoptimizedFrame(frame, code); + UNREACHABLE(); + } + current_frame++; } } } @@ -4290,36 +3581,6 @@ void Debugger::RewindToOptimizedFrame(StackFrame* frame, UNREACHABLE(); } -void Debugger::RewindToInterpretedFrame(StackFrame* frame, - const Bytecode& bytecode) { - // We will be jumping out of the debugger rather than exiting this - // function, so prepare the debugger state. - ClearCachedStackTraces(); - resume_action_ = kContinue; - resume_frame_index_ = -1; - EnterSingleStepMode(); - - uword rewind_pc = LookupRewindPc(bytecode, frame->pc()); - if (FLAG_trace_rewind && rewind_pc == 0) { - OS::PrintErr("Unable to find rewind pc for bytecode pc(%" Px ")\n", - frame->pc()); - } - ASSERT(rewind_pc != 0); - if (FLAG_trace_rewind) { - OS::PrintErr( - "===============================\n" - "Rewinding to interpreted frame:\n" - " rewind_pc(0x%" Px " offset:0x%" Px ") sp(0x%" Px ") fp(0x%" Px - ")\n" - "===============================\n", - rewind_pc, rewind_pc - bytecode.PayloadStart(), frame->sp(), - frame->fp()); - } - Exceptions::JumpToFrame(Thread::Current(), rewind_pc, frame->sp(), - frame->fp(), true /* clear lazy deopt at target */); - UNREACHABLE(); -} - void Debugger::RewindPostDeopt() { intptr_t rewind_frame = post_deopt_frame_index_; post_deopt_frame_index_ = -1; @@ -4404,23 +3665,6 @@ bool Debugger::IsAtAsyncJump(ActivationFrame* top_frame) { top_frame->function().IsAsyncGenClosure()); ASSERT(closure_or_null.IsInstance()); ASSERT(Instance::Cast(closure_or_null).IsClosure()); - if (top_frame->function().is_declared_in_bytecode()) { -#if !defined(DART_PRECOMPILED_RUNTIME) - const auto& bytecode = - Bytecode::Handle(zone, top_frame->function().bytecode()); - const TokenPosition token_pos = top_frame->TokenPos(); - kernel::BytecodeSourcePositionsIterator iter(zone, bytecode); - while (iter.MoveNext()) { - if (iter.IsYieldPoint() && (iter.TokenPos() == token_pos)) { - return true; - } - } - return false; -#else - UNREACHABLE(); -#endif // !defined(DART_PRECOMPILED_RUNTIME) - } - ASSERT(!top_frame->IsInterpreted()); const auto& pc_descriptors = PcDescriptors::Handle(zone, top_frame->code().pc_descriptors()); if (pc_descriptors.IsNull()) { @@ -4464,7 +3708,7 @@ ErrorPtr Debugger::PauseStepping() { // async machinery as we finish the async function. The second check // handles the case of returning from an async function. const ActivationFrame::Relation relation = - frame->CompareTo(async_stepping_fp_, interpreted_async_stepping_); + frame->CompareTo(async_stepping_fp_); const bool exited_async_function = (relation == ActivationFrame::kCallee && frame->IsAsyncMachinery()) || relation == ActivationFrame::kCaller; @@ -4481,8 +3725,7 @@ ErrorPtr Debugger::PauseStepping() { if (stepping_fp_ != 0) { // There is an "interesting frame" set. Only pause at appropriate // locations in this frame. - const ActivationFrame::Relation relation = - frame->CompareTo(stepping_fp_, interpreted_stepping_); + const ActivationFrame::Relation relation = frame->CompareTo(stepping_fp_); if (relation == ActivationFrame::kCallee) { // We are in a callee of the frame we're interested in. // Ignore this stepping break. @@ -4540,17 +3783,6 @@ ErrorPtr Debugger::PauseStepping() { return Error::null(); } - // In bytecode, do not stop before encountering the DebugCheck opcode. - // Skip this check if we previously stopped in this frame. - // If no DebugCheck was emitted, do not stop (InPrologue returns true). - if (frame->IsInterpreted() && frame->fp() != last_stepping_fp_) { - uword debug_check_pc = frame->bytecode().GetFirstDebugCheckOpcodePc(); - // Frame pc is return address, debug_check_pc is exact, so use '<=' in test. - if (debug_check_pc == 0 || frame->pc() <= debug_check_pc) { - return Error::null(); - } - } - // We are stopping in this frame at the token pos. last_stepping_fp_ = frame->fp(); last_stepping_pos_ = frame->TokenPos(); @@ -4561,15 +3793,13 @@ ErrorPtr Debugger::PauseStepping() { ASSERT(!HasActiveBreakpoint(frame->pc())); if (FLAG_verbose_debug) { - OS::PrintErr( - ">>> single step break at %s:%" Pd ":%" Pd - " (func %s token %s address %#" Px " offset %#" Px ")\n", - String::Handle(frame->SourceUrl()).ToCString(), frame->LineNumber(), - frame->ColumnNumber(), - String::Handle(frame->QualifiedFunctionName()).ToCString(), - frame->TokenPos().ToCString(), frame->pc(), - frame->pc() - (frame->IsInterpreted() ? frame->bytecode().PayloadStart() - : frame->code().PayloadStart())); + OS::PrintErr(">>> single step break at %s:%" Pd ":%" Pd + " (func %s token %s address %#" Px " offset %#" Px ")\n", + String::Handle(frame->SourceUrl()).ToCString(), + frame->LineNumber(), frame->ColumnNumber(), + String::Handle(frame->QualifiedFunctionName()).ToCString(), + frame->TokenPos().ToCString(), frame->pc(), + frame->pc() - frame->code().PayloadStart()); } CacheStackTraces(CollectStackTrace(), CollectAsyncCausalStackTrace(), @@ -4622,9 +3852,7 @@ ErrorPtr Debugger::PauseBreakpoint() { String::Handle(cbpt->SourceUrl()).ToCString(), cbpt->LineNumber(), String::Handle(top_frame->QualifiedFunctionName()).ToCString(), cbpt->token_pos().ToCString(), top_frame->pc(), - top_frame->pc() - (top_frame->IsInterpreted() - ? top_frame->bytecode().PayloadStart() - : top_frame->code().PayloadStart())); + top_frame->pc() - top_frame->code().PayloadStart()); } ASSERT(synthetic_async_breakpoint_ == NULL); @@ -4648,9 +3876,7 @@ ErrorPtr Debugger::PauseBreakpoint() { cbpt->LineNumber(), String::Handle(top_frame->QualifiedFunctionName()).ToCString(), cbpt->token_pos().ToCString(), top_frame->pc(), - top_frame->pc() - (top_frame->IsInterpreted() - ? top_frame->bytecode().PayloadStart() - : top_frame->code().PayloadStart())); + top_frame->pc() - top_frame->code().PayloadStart()); } CacheStackTraces(stack_trace, CollectAsyncCausalStackTrace(), @@ -4778,15 +4004,11 @@ TokenPosition Debugger::FindExactTokenPosition(const Script& script, } #endif // !defined(DART_PRECOMPILED_RUNTIME) -void Debugger::HandleCodeChange(bool bytecode_loaded, const Function& func) { +void Debugger::NotifyCompilation(const Function& func) { if (breakpoint_locations_ == NULL) { // Return with minimal overhead if there are no breakpoints. return; } - if (bytecode_loaded && !FLAG_enable_interpreter) { - // We do not set breakpoints in bytecode if the interpreter is not used. - return; - } if (!func.is_debuggable()) { // Nothing to do if the function is not debuggable. If there is // a pending breakpoint in an inner function (that is debuggable), @@ -4816,46 +4038,23 @@ void Debugger::HandleCodeChange(bool bytecode_loaded, const Function& func) { const Function& inner_function = Function::Handle(zone, FindInnermostClosure(func, token_pos)); if (!inner_function.IsNull()) { - if (bytecode_loaded) { - // func's bytecode was just loaded. - // If func is a closure and has an inner closure, the inner closure - // may not have been loaded yet. - if (inner_function.HasBytecode()) { - ASSERT(loc->IsResolved(bytecode_loaded)); - } else { - if (FLAG_verbose_debug) { - OS::PrintErr( - "Pending breakpoint remains unresolved in " - "inner bytecode function '%s'\n", - inner_function.ToFullyQualifiedCString()); - } - } - continue; - } else { - if (FLAG_verbose_debug) { - OS::PrintErr( - "Pending breakpoint remains unresolved in " - "inner function '%s'\n", - inner_function.ToFullyQualifiedCString()); - } - continue; + if (FLAG_verbose_debug) { + OS::PrintErr( + "Pending breakpoint remains unresolved in " + "inner function '%s'\n", + inner_function.ToFullyQualifiedCString()); } - - // TODO(hausner): What should we do if function is optimized? - // Can we deoptimize the function? - ASSERT(!func.HasOptimizedCode()); + continue; } // There is no local function within func that contains the // breakpoint token position. Resolve the breakpoint if necessary // and set the code breakpoints. - const bool resolved_in_bytecode = - !bytecode_loaded && loc->IsResolved(/* in_bytecode = */ true); - if (!loc->IsResolved(bytecode_loaded)) { + if (!loc->IsResolved()) { // Resolve source breakpoint in the newly compiled function. - TokenPosition bp_pos = ResolveBreakpointPos( - bytecode_loaded, func, loc->token_pos(), loc->end_token_pos(), - loc->requested_column_number(), token_pos); + TokenPosition bp_pos = + ResolveBreakpointPos(func, loc->token_pos(), loc->end_token_pos(), + loc->requested_column_number(), token_pos); if (!bp_pos.IsDebugPause()) { if (FLAG_verbose_debug) { OS::PrintErr("Failed resolving breakpoint for function '%s'\n", @@ -4865,7 +4064,7 @@ void Debugger::HandleCodeChange(bool bytecode_loaded, const Function& func) { } TokenPosition requested_pos = loc->token_pos(); TokenPosition requested_end_pos = loc->end_token_pos(); - loc->SetResolved(bytecode_loaded, func, bp_pos); + loc->SetResolved(func, bp_pos); Breakpoint* bpt = loc->breakpoints(); while (bpt != NULL) { if (FLAG_verbose_debug) { @@ -4877,15 +4076,11 @@ void Debugger::HandleCodeChange(bool bytecode_loaded, const Function& func) { func.ToFullyQualifiedCString(), requested_pos.ToCString(), requested_end_pos.ToCString(), loc->requested_column_number()); } - // Do not signal resolution in code if already signaled resolution - // in bytecode. - if (!resolved_in_bytecode) { - SendBreakpointEvent(ServiceEvent::kBreakpointResolved, bpt); - } + SendBreakpointEvent(ServiceEvent::kBreakpointResolved, bpt); bpt = bpt->next(); } } - ASSERT(loc->IsResolved(bytecode_loaded)); + ASSERT(loc->IsResolved()); if (FLAG_verbose_debug) { Breakpoint* bpt = loc->breakpoints(); while (bpt != NULL) { @@ -5167,7 +4362,6 @@ BreakpointLocation* Debugger::GetBreakpointLocation( TokenPosition token_pos, intptr_t requested_line, intptr_t requested_column, - TokenPosition bytecode_token_pos, TokenPosition code_token_pos) { BreakpointLocation* loc = breakpoint_locations_; while (loc != NULL) { @@ -5177,8 +4371,6 @@ BreakpointLocation* Debugger::GetBreakpointLocation( (loc->requested_line_number_ == requested_line)) && ((requested_column == -1) || (loc->requested_column_number_ == requested_column)) && - (!bytecode_token_pos.IsReal() || - (loc->bytecode_token_pos_ == bytecode_token_pos)) && (!code_token_pos.IsReal() || (loc->code_token_pos_ == code_token_pos))) { return loc; diff --git a/runtime/vm/debugger.h b/runtime/vm/debugger.h index 7a99640694c..e5fd4ace8e7 100644 --- a/runtime/vm/debugger.h +++ b/runtime/vm/debugger.h @@ -7,7 +7,6 @@ #include "include/dart_tools_api.h" -#include "vm/constants_kbc.h" #include "vm/kernel_isolate.h" #include "vm/object.h" #include "vm/port.h" @@ -152,21 +151,13 @@ class BreakpointLocation { bool for_over_await); bool AnyEnabled() const; - bool IsResolved() const { - return bytecode_token_pos_.IsReal() || code_token_pos_.IsReal(); - } - bool IsResolved(bool in_bytecode) const { - return in_bytecode ? bytecode_token_pos_.IsReal() - : code_token_pos_.IsReal(); - } + bool IsResolved() const { return code_token_pos_.IsReal(); } bool IsLatent() const { return !token_pos_.IsReal(); } private: void VisitObjectPointers(ObjectPointerVisitor* visitor); - void SetResolved(bool in_bytecode, - const Function& func, - TokenPosition token_pos); + void SetResolved(const Function& func, TokenPosition token_pos); BreakpointLocation* next() const { return this->next_; } void set_next(BreakpointLocation* value) { next_ = value; } @@ -187,14 +178,13 @@ class BreakpointLocation { // Valid for resolved breakpoints: FunctionPtr function_; - TokenPosition bytecode_token_pos_; TokenPosition code_token_pos_; friend class Debugger; DISALLOW_COPY_AND_ASSIGN(BreakpointLocation); }; -// CodeBreakpoint represents a location in compiled or interpreted code. +// CodeBreakpoint represents a location in compiled code. // There may be more than one CodeBreakpoint for one BreakpointLocation, // e.g. when a function gets compiled as a regular function and as a closure. class CodeBreakpoint { @@ -203,7 +193,6 @@ class CodeBreakpoint { TokenPosition token_pos, uword pc, PcDescriptorsLayout::Kind kind); - CodeBreakpoint(const Bytecode& bytecode, TokenPosition token_pos, uword pc); ~CodeBreakpoint(); FunctionPtr function() const; @@ -217,7 +206,6 @@ class CodeBreakpoint { void Enable(); void Disable(); bool IsEnabled() const { return is_enabled_; } - bool IsInterpreted() const { return bytecode_ != Bytecode::null(); } CodePtr OrigStubAddress() const; @@ -232,11 +220,8 @@ class CodeBreakpoint { void PatchCode(); void RestoreCode(); - void SetBytecodeBreakpoint(); - void UnsetBytecodeBreakpoint(); CodePtr code_; - BytecodePtr bytecode_; TokenPosition token_pos_; uword pc_; intptr_t line_number_; @@ -273,16 +258,6 @@ class ActivationFrame : public ZoneAllocated { ActivationFrame(uword pc, const Code& code); -#if !defined(DART_PRECOMPILED_RUNTIME) - ActivationFrame(uword pc, - uword fp, - uword sp, - const Bytecode& bytecode, - Kind kind = kRegular); - - ActivationFrame(uword pc, const Bytecode& bytecode); -#endif // !defined(DART_PRECOMPILED_RUNTIME) - explicit ActivationFrame(Kind kind); explicit ActivationFrame(const Closure& async_activation); @@ -291,11 +266,7 @@ class ActivationFrame : public ZoneAllocated { uword fp() const { return fp_; } uword sp() const { return sp_; } - uword GetCallerSp() const { - return fp() + - ((IsInterpreted() ? kKBCCallerSpSlotFromFp : kCallerSpSlotFromFp) * - kWordSize); - } + uword GetCallerSp() const { return fp() + (kCallerSpSlotFromFp * kWordSize); } const Function& function() const { return function_; @@ -304,11 +275,6 @@ class ActivationFrame : public ZoneAllocated { ASSERT(!code_.IsNull()); return code_; } - const Bytecode& bytecode() const { - ASSERT(!bytecode_.IsNull()); - return bytecode_; - } - bool IsInterpreted() const { return !bytecode_.IsNull(); } enum Relation { kCallee, @@ -316,7 +282,7 @@ class ActivationFrame : public ZoneAllocated { kCaller, }; - Relation CompareTo(uword other_fp, bool other_is_interpreted) const; + Relation CompareTo(uword other_fp) const; StringPtr QualifiedFunctionName(); StringPtr SourceUrl(); @@ -430,7 +396,6 @@ class ActivationFrame : public ZoneAllocated { // The anchor of the context chain for this function. Context& ctx_; Code& code_; - Bytecode& bytecode_; Function& function_; bool live_frame_; // Is this frame a live frame? bool token_pos_initialized_; @@ -473,7 +438,6 @@ class DebuggerStackTrace : public ZoneAllocated { void AddActivation(ActivationFrame* frame); void AddMarker(ActivationFrame::Kind marker); void AddAsyncCausalFrame(uword pc, const Code& code); - void AddAsyncCausalFrame(uword pc, const Bytecode& bytecode); ZoneGrowableArray trace_; @@ -508,12 +472,7 @@ class Debugger { void OnIsolateRunnable(); - void NotifyCompilation(const Function& func) { - HandleCodeChange(/* bytecode_loaded = */ false, func); - } - void NotifyBytecodeLoaded(const Function& func) { - HandleCodeChange(/* bytecode_loaded = */ true, func); - } + void NotifyCompilation(const Function& func); void NotifyDoneLoading(); // Set breakpoint at closest location to function entry. @@ -561,10 +520,6 @@ class Debugger { ignore_breakpoints_ = ignore_breakpoints; } - bool HasEnabledBytecodeBreakpoints() const; - // Called from the interpreter. Note that pc already points to next bytecode. - bool HasBytecodeBreakpointAt(const KBCInstr* next_pc) const; - // Put the isolate into single stepping mode when Dart code next runs. // // This is used by the vm service to allow the user to step while @@ -588,7 +543,6 @@ class Debugger { // debugger's zone. bool HasBreakpoint(const Function& func, Zone* zone); bool HasBreakpoint(const Code& code); - // A Bytecode version of HasBreakpoint is not needed. // Returns true if the call at address pc is patched to point to // a debugger stub. @@ -669,7 +623,6 @@ class Debugger { void FindCompiledFunctions(const Script& script, TokenPosition start_pos, TokenPosition end_pos, - GrowableObjectArray* bytecode_function_list, GrowableObjectArray* code_function_list); bool FindBestFit(const Script& script, TokenPosition token_pos, @@ -677,17 +630,14 @@ class Debugger { Function* best_fit); FunctionPtr FindInnermostClosure(const Function& function, TokenPosition token_pos); - TokenPosition ResolveBreakpointPos(bool in_bytecode, - const Function& func, + TokenPosition ResolveBreakpointPos(const Function& func, TokenPosition requested_token_pos, TokenPosition last_token_pos, intptr_t requested_column, TokenPosition exact_token_pos); void DeoptimizeWorld(); void NotifySingleStepping(bool value) const; - BreakpointLocation* SetCodeBreakpoints(bool in_bytecode, - BreakpointLocation* loc, - const Script& script, + BreakpointLocation* SetCodeBreakpoints(const Script& script, TokenPosition token_pos, TokenPosition last_token_pos, intptr_t requested_line, @@ -714,7 +664,6 @@ class Debugger { TokenPosition token_pos, intptr_t requested_line, intptr_t requested_column, - TokenPosition bytecode_token_pos = TokenPosition::kNoSource, TokenPosition code_token_pos = TokenPosition::kNoSource); void MakeCodeBreakpointAt(const Function& func, BreakpointLocation* bpt); // Returns NULL if no breakpoint exists for the given address. @@ -724,8 +673,6 @@ class Debugger { void PrintBreakpointsListToJSONArray(BreakpointLocation* sbpt, JSONArray* jsarr) const; - void HandleCodeChange(bool bytecode_loaded, const Function& func); - ActivationFrame* TopDartFrame() const; static ActivationFrame* CollectDartFrame( Isolate* isolate, @@ -736,12 +683,6 @@ class Debugger { intptr_t deopt_frame_offset, ActivationFrame::Kind kind = ActivationFrame::kRegular); #if !defined(DART_PRECOMPILED_RUNTIME) - static ActivationFrame* CollectDartFrame( - Isolate* isolate, - uword pc, - StackFrame* frame, - const Bytecode& bytecode, - ActivationFrame::Kind kind = ActivationFrame::kRegular); static ArrayPtr DeoptimizeToArray(Thread* thread, StackFrame* frame, const Code& code); @@ -789,7 +730,6 @@ class Debugger { void RewindToOptimizedFrame(StackFrame* frame, const Code& code, intptr_t post_deopt_frame_index); - void RewindToInterpretedFrame(StackFrame* frame, const Bytecode& bytecode); void ResetSteppingFramePointers(); bool SteppedForSyntheticAsyncBreakpoint() const; @@ -832,7 +772,6 @@ class Debugger { // frame corresponds to this fp value, or if the top frame is // lower on the stack. uword stepping_fp_; - bool interpreted_stepping_; // When stepping through code, do not stop more than once in the same // token position range. @@ -841,7 +780,6 @@ class Debugger { // Used to track the current async/async* function. uword async_stepping_fp_; - bool interpreted_async_stepping_; ObjectPtr top_frame_awaiter_; // If we step while at a breakpoint, we would hit the same pc twice. diff --git a/runtime/vm/debugger_kbc.cc b/runtime/vm/debugger_kbc.cc deleted file mode 100644 index c07d8e9bf33..00000000000 --- a/runtime/vm/debugger_kbc.cc +++ /dev/null @@ -1,56 +0,0 @@ -// Copyright (c) 2019, the Dart project authors. Please see the AUTHORS file -// for details. All rights reserved. Use of this source code is governed by a -// BSD-style license that can be found in the LICENSE file. - -#include "vm/globals.h" -#if !defined(DART_PRECOMPILED_RUNTIME) - -#include "vm/debugger.h" -#include "vm/instructions_kbc.h" -#include "vm/interpreter.h" - -namespace dart { - -#ifndef PRODUCT -void CodeBreakpoint::SetBytecodeBreakpoint() { - ASSERT(!is_enabled_); - is_enabled_ = true; - Interpreter::Current()->set_is_debugging(true); -} - -void CodeBreakpoint::UnsetBytecodeBreakpoint() { - ASSERT(is_enabled_); - is_enabled_ = false; - if (!Isolate::Current()->single_step() && - !Isolate::Current()->debugger()->HasEnabledBytecodeBreakpoints()) { - Interpreter::Current()->set_is_debugging(false); - } -} - -bool Debugger::HasEnabledBytecodeBreakpoints() const { - CodeBreakpoint* cbpt = code_breakpoints_; - while (cbpt != nullptr) { - if (cbpt->IsEnabled() && cbpt->IsInterpreted()) { - return true; - } - cbpt = cbpt->next(); - } - return false; -} - -bool Debugger::HasBytecodeBreakpointAt(const KBCInstr* next_pc) const { - CodeBreakpoint* cbpt = code_breakpoints_; - while (cbpt != nullptr) { - if ((reinterpret_cast(next_pc)) == cbpt->pc_ && cbpt->IsEnabled()) { - ASSERT(cbpt->IsInterpreted()); - return true; - } - cbpt = cbpt->next(); - } - return false; -} -#endif // !PRODUCT - -} // namespace dart - -#endif // !defined(DART_PRECOMPILED_RUNTIME) diff --git a/runtime/vm/deopt_instructions.cc b/runtime/vm/deopt_instructions.cc index e54dc1f95bd..54cac1a00bd 100644 --- a/runtime/vm/deopt_instructions.cc +++ b/runtime/vm/deopt_instructions.cc @@ -378,7 +378,6 @@ intptr_t DeoptContext::MaterializeDeferredObjects() { StackFrameIterator::kNoCrossThreadIteration); StackFrame* top_frame = iterator.NextFrame(); ASSERT(top_frame != NULL); - ASSERT(!top_frame->is_interpreted()); const Code& code = Code::Handle(top_frame->LookupDartCode()); const Function& top_function = Function::Handle(code.function()); const Script& script = Script::Handle(top_function.script()); diff --git a/runtime/vm/exceptions.cc b/runtime/vm/exceptions.cc index 9cba5d4b7d4..5e640c368ff 100644 --- a/runtime/vm/exceptions.cc +++ b/runtime/vm/exceptions.cc @@ -24,7 +24,6 @@ namespace dart { -DECLARE_FLAG(bool, enable_interpreter); DECLARE_FLAG(bool, trace_deoptimization); DEFINE_FLAG(bool, print_stacktrace_at_throw, @@ -129,26 +128,15 @@ static void BuildStackTrace(StackTraceBuilder* builder) { StackFrame* frame = frames.NextFrame(); ASSERT(frame != NULL); // We expect to find a dart invocation frame. Code& code = Code::Handle(); - Bytecode& bytecode = Bytecode::Handle(); Smi& offset = Smi::Handle(); for (; frame != NULL; frame = frames.NextFrame()) { if (!frame->IsDartFrame()) { continue; } - if (frame->is_interpreted()) { - bytecode = frame->LookupDartBytecode(); - ASSERT(bytecode.ContainsInstructionAt(frame->pc())); - if (bytecode.function() == Function::null()) { - continue; - } - offset = Smi::New(frame->pc() - bytecode.PayloadStart()); - builder->AddFrame(bytecode, offset); - } else { - code = frame->LookupDartCode(); - ASSERT(code.ContainsInstructionAt(frame->pc())); - offset = Smi::New(frame->pc() - code.PayloadStart()); - builder->AddFrame(code, offset); - } + code = frame->LookupDartCode(); + ASSERT(code.ContainsInstructionAt(frame->pc())); + offset = Smi::New(frame->pc() - code.PayloadStart()); + builder->AddFrame(code, offset); } } @@ -622,9 +610,7 @@ static void ClearLazyDeopts(Thread* thread, uword frame_pointer) { StackFrameIterator::kNoCrossThreadIteration); for (StackFrame* frame = frames.NextFrame(); frame != nullptr; frame = frames.NextFrame()) { - if (frame->is_interpreted()) { - continue; - } else if (frame->fp() >= frame_pointer) { + if (frame->fp() >= frame_pointer) { break; } if (frame->IsMarkedForLazyDeopt()) { @@ -677,18 +663,6 @@ void Exceptions::JumpToFrame(Thread* thread, uword stack_pointer, uword frame_pointer, bool clear_deopt_at_target) { -#if !defined(DART_PRECOMPILED_RUNTIME) - // TODO(regis): We still possibly need to unwind interpreter frames if they - // are callee frames of the C++ frame handling the exception. - if (FLAG_enable_interpreter) { - Interpreter* interpreter = thread->interpreter(); - if ((interpreter != NULL) && interpreter->HasFrame(frame_pointer)) { - interpreter->JumpToFrame(program_counter, stack_pointer, frame_pointer, - thread); - } - } -#endif // !defined(DART_PRECOMPILED_RUNTIME) - const uword fp_for_clearing = (clear_deopt_at_target ? frame_pointer + 1 : frame_pointer); ClearLazyDeopts(thread, fp_for_clearing); diff --git a/runtime/vm/flag_list.h b/runtime/vm/flag_list.h index 279db5e11ee..51e4a3ff667 100644 --- a/runtime/vm/flag_list.h +++ b/runtime/vm/flag_list.h @@ -96,9 +96,6 @@ constexpr bool kDartUseBackgroundCompilation = true; "Collects all dynamic function names to identify unique targets") \ P(compactor_tasks, int, 2, \ "The number of tasks to use for parallel compaction.") \ - P(compilation_counter_threshold, int, 10, \ - "Function's usage-counter value before interpreted function is compiled, " \ - "-1 means never") \ P(concurrent_mark, bool, true, "Concurrent mark for old generation.") \ P(concurrent_sweep, bool, true, "Concurrent sweep for old generation.") \ C(deoptimize_alot, false, false, bool, false, \ @@ -219,7 +216,6 @@ constexpr bool kDartUseBackgroundCompilation = true; D(trace_zones, bool, false, "Traces allocation sizes in the zone.") \ P(truncating_left_shift, bool, true, \ "Optimize left shift to truncate if possible") \ - P(use_bytecode_compiler, bool, false, "Compile from bytecode") \ P(use_compactor, bool, false, "Compact the heap during old-space GC.") \ P(use_cha_deopt, bool, true, \ "Use class hierarchy analysis even if it can cause deoptimization.") \ @@ -242,7 +238,6 @@ constexpr bool kDartUseBackgroundCompilation = true; "Enable magical pragmas for testing purposes. Use at your own risk!") \ R(eliminate_type_checks, true, bool, true, \ "Eliminate type checks when allowed by static type analysis.") \ - P(enable_interpreter, bool, false, "Enable interpreting kernel bytecode.") \ D(support_rr, bool, false, "Support running within RR.") \ P(verify_entry_points, bool, false, \ "Throw API error on invalid member access throuh native API. See " \ diff --git a/runtime/vm/gdb_helpers.cc b/runtime/vm/gdb_helpers.cc index f75c89a179b..61baa78c359 100644 --- a/runtime/vm/gdb_helpers.cc +++ b/runtime/vm/gdb_helpers.cc @@ -53,26 +53,6 @@ void _printGeneratedStackTrace(uword fp, uword sp, uword pc) { } } -// Like _printDartStackTrace, but works in the interpreter loop. -// Must be called with the current interpreter fp, sp, and pc. -// Note that sp[0] is not modified, but sp[1] will be trashed. -DART_EXPORT -void _printInterpreterStackTrace(ObjectPtr* fp, - ObjectPtr* sp, - const KBCInstr* pc) { - Thread* thread = Thread::Current(); - sp[1] = Function::null(); - sp[2] = Bytecode::null(); - sp[3] = static_cast(reinterpret_cast(pc)); - sp[4] = static_cast(reinterpret_cast(fp)); - ObjectPtr* exit_fp = sp + 1 + kKBCDartFrameFixedSize; - thread->set_top_exit_frame_info(reinterpret_cast(exit_fp)); - thread->set_execution_state(Thread::kThreadInVM); - _printDartStackTrace(); - thread->set_execution_state(Thread::kThreadInGenerated); - thread->set_top_exit_frame_info(0); -} - class PrintObjectPointersVisitor : public ObjectPointerVisitor { public: PrintObjectPointersVisitor() diff --git a/runtime/vm/heap/marker.cc b/runtime/vm/heap/marker.cc index 186d6fdbc99..0e306f7296e 100644 --- a/runtime/vm/heap/marker.cc +++ b/runtime/vm/heap/marker.cc @@ -312,20 +312,6 @@ class MarkingWeakVisitor : public HandleVisitor { void GCMarker::Prologue() { isolate_group_->ReleaseStoreBuffers(); - -#ifndef DART_PRECOMPILED_RUNTIME - isolate_group_->ForEachIsolate( - [&](Isolate* isolate) { - Thread* mutator_thread = isolate->mutator_thread(); - if (mutator_thread != NULL) { - Interpreter* interpreter = mutator_thread->interpreter(); - if (interpreter != NULL) { - interpreter->ClearLookupCache(); - } - } - }, - /*at_safepoint=*/true); -#endif } void GCMarker::Epilogue() {} diff --git a/runtime/vm/heap/weak_code.cc b/runtime/vm/heap/weak_code.cc index 795eda1a064..c1a3d530f79 100644 --- a/runtime/vm/heap/weak_code.cc +++ b/runtime/vm/heap/weak_code.cc @@ -76,12 +76,10 @@ void WeakCodeReferences::DisableCode() { StackFrameIterator::kNoCrossThreadIteration); StackFrame* frame = iterator.NextFrame(); while (frame != NULL) { - if (!frame->is_interpreted()) { - code = frame->LookupDartCode(); - if (IsOptimizedCode(code_objects, code)) { - ReportDeoptimization(code); - DeoptimizeAt(code, frame); - } + code = frame->LookupDartCode(); + if (IsOptimizedCode(code_objects, code)) { + ReportDeoptimization(code); + DeoptimizeAt(code, frame); } frame = iterator.NextFrame(); } diff --git a/runtime/vm/instructions_kbc.cc b/runtime/vm/instructions_kbc.cc deleted file mode 100644 index b4277387898..00000000000 --- a/runtime/vm/instructions_kbc.cc +++ /dev/null @@ -1,47 +0,0 @@ -// Copyright (c) 2018, the Dart project authors. Please see the AUTHORS file -// for details. All rights reserved. Use of this source code is governed by a -// BSD-style license that can be found in the LICENSE file. - -#include "vm/globals.h" -#if !defined(DART_PRECOMPILED_RUNTIME) - -#include "vm/instructions.h" -#include "vm/instructions_kbc.h" - -#include "vm/constants_kbc.h" -#include "vm/native_entry.h" - -namespace dart { - -TypedDataPtr KBCNativeCallPattern::GetNativeEntryDataAt( - uword pc, - const Bytecode& bytecode) { - ASSERT(bytecode.ContainsInstructionAt(pc)); - - const KBCInstr* return_addr = reinterpret_cast(pc); - const KBCInstr* instr = - reinterpret_cast(bytecode.PayloadStart()); - ASSERT(instr < return_addr); - while (!KernelBytecode::IsNativeCallOpcode(instr)) { - instr = KernelBytecode::Next(instr); - if (instr >= return_addr) { - FATAL1( - "Unable to find NativeCall bytecode instruction" - " corresponding to PC %" Px, - pc); - } - } - - intptr_t native_entry_data_pool_index = KernelBytecode::DecodeD(instr); - const ObjectPool& obj_pool = ObjectPool::Handle(bytecode.object_pool()); - TypedData& native_entry_data = TypedData::Handle(); - native_entry_data ^= obj_pool.ObjectAt(native_entry_data_pool_index); - // Native calls to recognized functions should never be patched. - ASSERT(NativeEntryData(native_entry_data).kind() == - MethodRecognizer::kUnknown); - return native_entry_data.raw(); -} - -} // namespace dart - -#endif // !defined(DART_PRECOMPILED_RUNTIME) diff --git a/runtime/vm/instructions_kbc.h b/runtime/vm/instructions_kbc.h deleted file mode 100644 index 5bfdb11ab83..00000000000 --- a/runtime/vm/instructions_kbc.h +++ /dev/null @@ -1,25 +0,0 @@ -// Copyright (c) 2018, the Dart project authors. Please see the AUTHORS file -// for details. All rights reserved. Use of this source code is governed by a -// BSD-style license that can be found in the LICENSE file. -// Classes that describe assembly patterns as used by inline caches. - -#ifndef RUNTIME_VM_INSTRUCTIONS_KBC_H_ -#define RUNTIME_VM_INSTRUCTIONS_KBC_H_ - -#include "vm/globals.h" -#if !defined(DART_PRECOMPILED_RUNTIME) - -#include "vm/object.h" - -namespace dart { - -class KBCNativeCallPattern : public AllStatic { - public: - static TypedDataPtr GetNativeEntryDataAt(uword pc, const Bytecode& bytecode); -}; - -#endif // !defined(DART_PRECOMPILED_RUNTIME) - -} // namespace dart - -#endif // RUNTIME_VM_INSTRUCTIONS_KBC_H_ diff --git a/runtime/vm/interpreter.cc b/runtime/vm/interpreter.cc deleted file mode 100644 index 38a0159610e..00000000000 --- a/runtime/vm/interpreter.cc +++ /dev/null @@ -1,3991 +0,0 @@ -// Copyright (c) 2018, the Dart project authors. Please see the AUTHORS file -// for details. All rights reserved. Use of this source code is governed by a -// BSD-style license that can be found in the LICENSE file. - -#include // NOLINT -#include - -#include "vm/globals.h" -#if !defined(DART_PRECOMPILED_RUNTIME) - -#include "vm/interpreter.h" - -#include "vm/class_id.h" -#include "vm/compiler/api/type_check_mode.h" -#include "vm/compiler/assembler/assembler.h" -#include "vm/compiler/assembler/disassembler_kbc.h" -#include "vm/compiler/backend/flow_graph_compiler.h" -#include "vm/compiler/ffi/abi.h" -#include "vm/compiler/frontend/bytecode_reader.h" -#include "vm/compiler/jit/compiler.h" -#include "vm/cpu.h" -#include "vm/dart_entry.h" -#include "vm/debugger.h" -#include "vm/lockers.h" -#include "vm/native_arguments.h" -#include "vm/native_entry.h" -#include "vm/object.h" -#include "vm/object_store.h" -#include "vm/os_thread.h" -#include "vm/stack_frame_kbc.h" -#include "vm/symbols.h" - -namespace dart { - -DEFINE_FLAG(uint64_t, - trace_interpreter_after, - ULLONG_MAX, - "Trace interpreter execution after instruction count reached."); -DEFINE_FLAG(charp, - interpreter_trace_file, - NULL, - "File to write a dynamic instruction trace to."); -DEFINE_FLAG(uint64_t, - interpreter_trace_file_max_bytes, - 100 * MB, - "Maximum size in bytes of the interpreter trace file"); - -// InterpreterSetjmpBuffer are linked together, and the last created one -// is referenced by the Interpreter. When an exception is thrown, the exception -// runtime looks at where to jump and finds the corresponding -// InterpreterSetjmpBuffer based on the stack pointer of the exception handler. -// The runtime then does a Longjmp on that buffer to return to the interpreter. -class InterpreterSetjmpBuffer { - public: - void Longjmp() { - // "This" is now the last setjmp buffer. - interpreter_->set_last_setjmp_buffer(this); - longjmp(buffer_, 1); - } - - explicit InterpreterSetjmpBuffer(Interpreter* interpreter) { - interpreter_ = interpreter; - link_ = interpreter->last_setjmp_buffer(); - interpreter->set_last_setjmp_buffer(this); - fp_ = interpreter->fp_; - } - - ~InterpreterSetjmpBuffer() { - ASSERT(interpreter_->last_setjmp_buffer() == this); - interpreter_->set_last_setjmp_buffer(link_); - } - - InterpreterSetjmpBuffer* link() const { return link_; } - - uword fp() const { return reinterpret_cast(fp_); } - - jmp_buf buffer_; - - private: - ObjectPtr* fp_; - Interpreter* interpreter_; - InterpreterSetjmpBuffer* link_; - - friend class Interpreter; - - DISALLOW_ALLOCATION(); - DISALLOW_COPY_AND_ASSIGN(InterpreterSetjmpBuffer); -}; - -DART_FORCE_INLINE static ObjectPtr* SavedCallerFP(ObjectPtr* FP) { - return reinterpret_cast( - static_cast(FP[kKBCSavedCallerFpSlotFromFp])); -} - -DART_FORCE_INLINE static ObjectPtr* FrameArguments(ObjectPtr* FP, - intptr_t argc) { - return FP - (kKBCDartFrameFixedSize + argc); -} - -#define RAW_CAST(Type, val) (InterpreterHelpers::CastTo##Type(val)) - -class InterpreterHelpers { - public: -#define DEFINE_CASTS(Type) \ - DART_FORCE_INLINE static Type##Ptr CastTo##Type(ObjectPtr obj) { \ - ASSERT((k##Type##Cid == kSmiCid) \ - ? !obj->IsHeapObject() \ - : (k##Type##Cid == kIntegerCid) \ - ? (!obj->IsHeapObject() || obj->IsMint()) \ - : obj->Is##Type()); \ - return static_cast(obj); \ - } - CLASS_LIST(DEFINE_CASTS) -#undef DEFINE_CASTS - - DART_FORCE_INLINE static SmiPtr GetClassIdAsSmi(ObjectPtr obj) { - return Smi::New(obj->IsHeapObject() ? obj->GetClassId() - : static_cast(kSmiCid)); - } - - DART_FORCE_INLINE static intptr_t GetClassId(ObjectPtr obj) { - return obj->IsHeapObject() ? obj->GetClassId() - : static_cast(kSmiCid); - } - - DART_FORCE_INLINE static TypeArgumentsPtr GetTypeArguments( - Thread* thread, - InstancePtr instance) { - ClassPtr instance_class = - thread->isolate()->class_table()->At(GetClassId(instance)); - return instance_class->ptr()->num_type_arguments_ > 0 - ? reinterpret_cast(instance->ptr()) - [instance_class->ptr() - ->host_type_arguments_field_offset_in_words_] - : TypeArguments::null(); - } - - // The usage counter is actually a 'hotness' counter. - // For an instance call, both the usage counters of the caller and of the - // calle will get incremented, as well as the ICdata counter at the call site. - DART_FORCE_INLINE static void IncrementUsageCounter(FunctionPtr f) { - f->ptr()->usage_counter_++; - } - - DART_FORCE_INLINE static void IncrementICUsageCount(ObjectPtr* entries, - intptr_t offset, - intptr_t args_tested) { - const intptr_t count_offset = ICData::CountIndexFor(args_tested); - const intptr_t raw_smi_old = - static_cast(entries[offset + count_offset]); - const intptr_t raw_smi_new = raw_smi_old + Smi::RawValue(1); - *reinterpret_cast(&entries[offset + count_offset]) = raw_smi_new; - } - - DART_FORCE_INLINE static bool CheckIndex(SmiPtr index, SmiPtr length) { - return !index->IsHeapObject() && (static_cast(index) >= 0) && - (static_cast(index) < static_cast(length)); - } - - DART_FORCE_INLINE static intptr_t ArgDescTypeArgsLen(ArrayPtr argdesc) { - return Smi::Value(*reinterpret_cast( - reinterpret_cast(argdesc->ptr()) + - Array::element_offset(ArgumentsDescriptor::kTypeArgsLenIndex))); - } - - DART_FORCE_INLINE static intptr_t ArgDescArgCount(ArrayPtr argdesc) { - return Smi::Value(*reinterpret_cast( - reinterpret_cast(argdesc->ptr()) + - Array::element_offset(ArgumentsDescriptor::kCountIndex))); - } - - DART_FORCE_INLINE static intptr_t ArgDescArgSize(ArrayPtr argdesc) { - return Smi::Value(*reinterpret_cast( - reinterpret_cast(argdesc->ptr()) + - Array::element_offset(ArgumentsDescriptor::kSizeIndex))); - } - - DART_FORCE_INLINE static intptr_t ArgDescPosCount(ArrayPtr argdesc) { - return Smi::Value(*reinterpret_cast( - reinterpret_cast(argdesc->ptr()) + - Array::element_offset(ArgumentsDescriptor::kPositionalCountIndex))); - } - - DART_FORCE_INLINE static BytecodePtr FrameBytecode(ObjectPtr* FP) { - ASSERT(GetClassId(FP[kKBCPcMarkerSlotFromFp]) == kBytecodeCid); - return static_cast(FP[kKBCPcMarkerSlotFromFp]); - } - - DART_FORCE_INLINE static bool FieldNeedsGuardUpdate(FieldPtr field, - ObjectPtr value) { - // The interpreter should never see a cloned field. - ASSERT(field->ptr()->owner_->GetClassId() != kFieldCid); - - const classid_t guarded_cid = field->ptr()->guarded_cid_; - - if (guarded_cid == kDynamicCid) { - // Field is not guarded. - return false; - } - - ASSERT(Isolate::Current()->use_field_guards()); - - const classid_t nullability_cid = field->ptr()->is_nullable_; - const classid_t value_cid = InterpreterHelpers::GetClassId(value); - - if (nullability_cid == value_cid) { - // Storing null into a nullable field. - return false; - } - - if (guarded_cid != value_cid) { - // First assignment (guarded_cid == kIllegalCid) or - // field no longer monomorphic or - // field has become nullable. - return true; - } - - intptr_t guarded_list_length = - Smi::Value(field->ptr()->guarded_list_length_); - - if (UNLIKELY(guarded_list_length >= Field::kUnknownFixedLength)) { - // Guarding length, check this in the runtime. - return true; - } - - if (UNLIKELY(field->ptr()->static_type_exactness_state_ >= - StaticTypeExactnessState::Uninitialized().Encode())) { - // Guarding "exactness", check this in the runtime. - return true; - } - - // Everything matches. - return false; - } - - DART_FORCE_INLINE static bool IsAllocateFinalized(ClassPtr cls) { - return Class::ClassFinalizedBits::decode(cls->ptr()->state_bits_) == - ClassLayout::kAllocateFinalized; - } -}; - -DART_FORCE_INLINE static const KBCInstr* SavedCallerPC(ObjectPtr* FP) { - return reinterpret_cast( - static_cast(FP[kKBCSavedCallerPcSlotFromFp])); -} - -DART_FORCE_INLINE static FunctionPtr FrameFunction(ObjectPtr* FP) { - FunctionPtr function = static_cast(FP[kKBCFunctionSlotFromFp]); - ASSERT(InterpreterHelpers::GetClassId(function) == kFunctionCid || - InterpreterHelpers::GetClassId(function) == kNullCid); - return function; -} - -DART_FORCE_INLINE static ObjectPtr InitializeHeader(uword addr, - intptr_t class_id, - intptr_t instance_size) { - uint32_t tags = 0; - tags = ObjectLayout::ClassIdTag::update(class_id, tags); - tags = ObjectLayout::SizeTag::update(instance_size, tags); - tags = ObjectLayout::OldBit::update(false, tags); - tags = ObjectLayout::OldAndNotMarkedBit::update(false, tags); - tags = ObjectLayout::OldAndNotRememberedBit::update(false, tags); - tags = ObjectLayout::NewBit::update(true, tags); - // Also writes zero in the hash_ field. - *reinterpret_cast(addr + Object::tags_offset()) = tags; - return ObjectLayout::FromAddr(addr); -} - -DART_FORCE_INLINE static bool TryAllocate(Thread* thread, - intptr_t class_id, - intptr_t instance_size, - ObjectPtr* result) { - ASSERT(instance_size > 0); - ASSERT(Utils::IsAligned(instance_size, kObjectAlignment)); - -#ifndef PRODUCT - auto table = thread->isolate_group()->shared_class_table(); - if (UNLIKELY(table->TraceAllocationFor(class_id))) { - return false; - } -#endif - const uword top = thread->top(); - const intptr_t remaining = thread->end() - top; - if (LIKELY(remaining >= instance_size)) { - thread->set_top(top + instance_size); - *result = InitializeHeader(top, class_id, instance_size); - return true; - } - return false; -} - -void LookupCache::Clear() { - for (intptr_t i = 0; i < kNumEntries; i++) { - entries_[i].receiver_cid = kIllegalCid; - } -} - -bool LookupCache::Lookup(intptr_t receiver_cid, - StringPtr function_name, - ArrayPtr arguments_descriptor, - FunctionPtr* target) const { - ASSERT(receiver_cid != kIllegalCid); // Sentinel value. - - const intptr_t hash = receiver_cid ^ static_cast(function_name) ^ - static_cast(arguments_descriptor); - const intptr_t probe1 = hash & kTableMask; - if (entries_[probe1].receiver_cid == receiver_cid && - entries_[probe1].function_name == function_name && - entries_[probe1].arguments_descriptor == arguments_descriptor) { - *target = entries_[probe1].target; - return true; - } - - intptr_t probe2 = (hash >> 3) & kTableMask; - if (entries_[probe2].receiver_cid == receiver_cid && - entries_[probe2].function_name == function_name && - entries_[probe2].arguments_descriptor == arguments_descriptor) { - *target = entries_[probe2].target; - return true; - } - - return false; -} - -void LookupCache::Insert(intptr_t receiver_cid, - StringPtr function_name, - ArrayPtr arguments_descriptor, - FunctionPtr target) { - // Otherwise we have to clear the cache or rehash on scavenges too. - ASSERT(function_name->IsOldObject()); - ASSERT(arguments_descriptor->IsOldObject()); - ASSERT(target->IsOldObject()); - - const intptr_t hash = receiver_cid ^ static_cast(function_name) ^ - static_cast(arguments_descriptor); - const intptr_t probe1 = hash & kTableMask; - if (entries_[probe1].receiver_cid == kIllegalCid) { - entries_[probe1].receiver_cid = receiver_cid; - entries_[probe1].function_name = function_name; - entries_[probe1].arguments_descriptor = arguments_descriptor; - entries_[probe1].target = target; - return; - } - - const intptr_t probe2 = (hash >> 3) & kTableMask; - if (entries_[probe2].receiver_cid == kIllegalCid) { - entries_[probe2].receiver_cid = receiver_cid; - entries_[probe2].function_name = function_name; - entries_[probe2].arguments_descriptor = arguments_descriptor; - entries_[probe2].target = target; - return; - } - - entries_[probe1].receiver_cid = receiver_cid; - entries_[probe1].function_name = function_name; - entries_[probe1].arguments_descriptor = arguments_descriptor; - entries_[probe1].target = target; -} - -Interpreter::Interpreter() - : stack_(NULL), - fp_(NULL), - pp_(nullptr), - argdesc_(nullptr), - lookup_cache_() { - // Setup interpreter support first. Some of this information is needed to - // setup the architecture state. - // We allocate the stack here, the size is computed as the sum of - // the size specified by the user and the buffer space needed for - // handling stack overflow exceptions. To be safe in potential - // stack underflows we also add some underflow buffer space. - stack_ = new uintptr_t[(OSThread::GetSpecifiedStackSize() + - OSThread::kStackSizeBufferMax + - kInterpreterStackUnderflowSize) / - sizeof(uintptr_t)]; - // Low address. - stack_base_ = - reinterpret_cast(stack_) + kInterpreterStackUnderflowSize; - // Limit for StackOverflowError. - overflow_stack_limit_ = stack_base_ + OSThread::GetSpecifiedStackSize(); - // High address. - stack_limit_ = overflow_stack_limit_ + OSThread::kStackSizeBufferMax; - - last_setjmp_buffer_ = NULL; - - DEBUG_ONLY(icount_ = 1); // So that tracing after 0 traces first bytecode. - -#if defined(DEBUG) - trace_file_bytes_written_ = 0; - trace_file_ = NULL; - if (FLAG_interpreter_trace_file != NULL) { - Dart_FileOpenCallback file_open = Dart::file_open_callback(); - if (file_open != NULL) { - trace_file_ = file_open(FLAG_interpreter_trace_file, /* write */ true); - trace_buffer_ = new KBCInstr[kTraceBufferInstrs]; - trace_buffer_idx_ = 0; - } - } -#endif - // Make sure interpreter's unboxing view is consistent with compiler. - supports_unboxed_doubles_ = FlowGraphCompiler::SupportsUnboxedDoubles(); - supports_unboxed_simd128_ = FlowGraphCompiler::SupportsUnboxedSimd128(); -} - -Interpreter::~Interpreter() { - delete[] stack_; - pp_ = NULL; - argdesc_ = NULL; -#if defined(DEBUG) - if (trace_file_ != NULL) { - FlushTraceBuffer(); - // Close the file. - Dart_FileCloseCallback file_close = Dart::file_close_callback(); - if (file_close != NULL) { - file_close(trace_file_); - trace_file_ = NULL; - delete[] trace_buffer_; - trace_buffer_ = NULL; - } - } -#endif -} - -// Get the active Interpreter for the current isolate. -Interpreter* Interpreter::Current() { - Thread* thread = Thread::Current(); - Interpreter* interpreter = thread->interpreter(); - if (interpreter == nullptr) { - NoSafepointScope no_safepoint; - interpreter = new Interpreter(); - thread->set_interpreter(interpreter); - } - return interpreter; -} - -#if defined(DEBUG) -// Returns true if tracing of executed instructions is enabled. -// May be called on entry, when icount_ has not been incremented yet. -DART_FORCE_INLINE bool Interpreter::IsTracingExecution() const { - return icount_ > FLAG_trace_interpreter_after; -} - -// Prints bytecode instruction at given pc for instruction tracing. -DART_NOINLINE void Interpreter::TraceInstruction(const KBCInstr* pc) const { - THR_Print("%" Pu64 " ", icount_); - if (FLAG_support_disassembler) { - KernelBytecodeDisassembler::Disassemble( - reinterpret_cast(pc), - reinterpret_cast(KernelBytecode::Next(pc))); - } else { - THR_Print("Disassembler not supported in this mode.\n"); - } -} - -DART_FORCE_INLINE bool Interpreter::IsWritingTraceFile() const { - return (trace_file_ != NULL) && - (trace_file_bytes_written_ < FLAG_interpreter_trace_file_max_bytes); -} - -void Interpreter::FlushTraceBuffer() { - Dart_FileWriteCallback file_write = Dart::file_write_callback(); - if (file_write == NULL) { - return; - } - if (trace_file_bytes_written_ >= FLAG_interpreter_trace_file_max_bytes) { - return; - } - const intptr_t bytes_to_write = Utils::Minimum( - static_cast(trace_buffer_idx_ * sizeof(KBCInstr)), - FLAG_interpreter_trace_file_max_bytes - trace_file_bytes_written_); - if (bytes_to_write == 0) { - return; - } - file_write(trace_buffer_, bytes_to_write, trace_file_); - trace_file_bytes_written_ += bytes_to_write; - trace_buffer_idx_ = 0; -} - -DART_NOINLINE void Interpreter::WriteInstructionToTrace(const KBCInstr* pc) { - Dart_FileWriteCallback file_write = Dart::file_write_callback(); - if (file_write == NULL) { - return; - } - const KBCInstr* next = KernelBytecode::Next(pc); - while ((trace_buffer_idx_ < kTraceBufferInstrs) && (pc != next)) { - trace_buffer_[trace_buffer_idx_++] = *pc; - ++pc; - } - if (trace_buffer_idx_ == kTraceBufferInstrs) { - FlushTraceBuffer(); - } -} - -#endif // defined(DEBUG) - -// Calls into the Dart runtime are based on this interface. -typedef void (*InterpreterRuntimeCall)(NativeArguments arguments); - -// Calls to leaf Dart runtime functions are based on this interface. -typedef intptr_t (*InterpreterLeafRuntimeCall)(intptr_t r0, - intptr_t r1, - intptr_t r2, - intptr_t r3); - -// Calls to leaf float Dart runtime functions are based on this interface. -typedef double (*InterpreterLeafFloatRuntimeCall)(double d0, double d1); - -void Interpreter::Exit(Thread* thread, - ObjectPtr* base, - ObjectPtr* frame, - const KBCInstr* pc) { - frame[0] = Function::null(); - frame[1] = Bytecode::null(); - frame[2] = static_cast(reinterpret_cast(pc)); - frame[3] = static_cast(reinterpret_cast(base)); - - ObjectPtr* exit_fp = frame + kKBCDartFrameFixedSize; - thread->set_top_exit_frame_info(reinterpret_cast(exit_fp)); - fp_ = exit_fp; - -#if defined(DEBUG) - if (IsTracingExecution()) { - THR_Print("%" Pu64 " ", icount_); - THR_Print("Exiting interpreter 0x%" Px " at fp_ 0x%" Px "\n", - reinterpret_cast(this), reinterpret_cast(exit_fp)); - } -#endif -} - -void Interpreter::Unexit(Thread* thread) { -#if !defined(PRODUCT) - // For the profiler. - ObjectPtr* exit_fp = - reinterpret_cast(thread->top_exit_frame_info()); - ASSERT(exit_fp != 0); - pc_ = SavedCallerPC(exit_fp); - fp_ = SavedCallerFP(exit_fp); -#endif - thread->set_top_exit_frame_info(0); -} - -// Calling into runtime may trigger garbage collection and relocate objects, -// so all ObjectPtr pointers become outdated and should not be used across -// runtime calls. -// Note: functions below are marked DART_NOINLINE to recover performance where -// inlining these functions into the interpreter loop seemed to cause some code -// quality issues. Functions with the "returns_twice" attribute, such as setjmp, -// prevent reusing spill slots and large frame sizes. -static DART_NOINLINE bool InvokeRuntime(Thread* thread, - Interpreter* interpreter, - RuntimeFunction drt, - const NativeArguments& args) { - InterpreterSetjmpBuffer buffer(interpreter); - if (!setjmp(buffer.buffer_)) { - thread->set_vm_tag(reinterpret_cast(drt)); - drt(args); - thread->set_vm_tag(VMTag::kDartInterpretedTagId); - interpreter->Unexit(thread); - return true; - } else { - return false; - } -} - -static DART_NOINLINE bool InvokeNative(Thread* thread, - Interpreter* interpreter, - NativeFunctionWrapper wrapper, - Dart_NativeFunction function, - Dart_NativeArguments args) { - InterpreterSetjmpBuffer buffer(interpreter); - if (!setjmp(buffer.buffer_)) { - thread->set_vm_tag(reinterpret_cast(function)); - wrapper(args, function); - thread->set_vm_tag(VMTag::kDartInterpretedTagId); - interpreter->Unexit(thread); - return true; - } else { - return false; - } -} - -extern "C" { -// Note: The invocation stub follows the C ABI, so we cannot pass C++ struct -// values like ObjectPtr. In some calling conventions (IA32), ObjectPtr is -// passed/returned different from a pointer. -typedef uword /*ObjectPtr*/ (*invokestub)(uword /*CodePtr*/ code, - uword /*ArrayPtr*/ argdesc, - ObjectPtr* arg0, - Thread* thread); -} - -DART_NOINLINE bool Interpreter::InvokeCompiled(Thread* thread, - FunctionPtr function, - ObjectPtr* call_base, - ObjectPtr* call_top, - const KBCInstr** pc, - ObjectPtr** FP, - ObjectPtr** SP) { - ASSERT(Function::HasCode(function)); - CodePtr code = function->ptr()->code_; - ASSERT(code != StubCode::LazyCompile().raw()); - // TODO(regis): Once we share the same stack, try to invoke directly. -#if defined(DEBUG) - if (IsTracingExecution()) { - THR_Print("%" Pu64 " ", icount_); - THR_Print("invoking compiled %s\n", Function::Handle(function).ToCString()); - } -#endif - // On success, returns a RawInstance. On failure, a RawError. - invokestub volatile entrypoint = reinterpret_cast( - StubCode::InvokeDartCodeFromBytecode().EntryPoint()); - ObjectPtr result; - Exit(thread, *FP, call_top + 1, *pc); - { - InterpreterSetjmpBuffer buffer(this); - if (!setjmp(buffer.buffer_)) { -#if defined(USING_SIMULATOR) - // We need to beware that bouncing between the interpreter and the - // simulator may exhaust the C stack before exhausting either the - // interpreter or simulator stacks. - if (!thread->os_thread()->HasStackHeadroom()) { - thread->SetStackLimit(-1); - } - result = bit_copy(Simulator::Current()->Call( - reinterpret_cast(entrypoint), static_cast(code), - static_cast(argdesc_), - reinterpret_cast(call_base), - reinterpret_cast(thread))); -#else - result = static_cast(entrypoint(static_cast(code), - static_cast(argdesc_), - call_base, thread)); -#endif - ASSERT(thread->vm_tag() == VMTag::kDartInterpretedTagId); - ASSERT(thread->execution_state() == Thread::kThreadInGenerated); - Unexit(thread); - } else { - return false; - } - } - // Pop args and push result. - *SP = call_base; - **SP = result; - pp_ = InterpreterHelpers::FrameBytecode(*FP)->ptr()->object_pool_; - - // If the result is an error (not a Dart instance), it must either be rethrown - // (in the case of an unhandled exception) or it must be returned to the - // caller of the interpreter to be propagated. - if (result->IsHeapObject()) { - const intptr_t result_cid = result->GetClassId(); - if (result_cid == kUnhandledExceptionCid) { - (*SP)[0] = UnhandledException::RawCast(result)->ptr()->exception_; - (*SP)[1] = UnhandledException::RawCast(result)->ptr()->stacktrace_; - (*SP)[2] = 0; // Space for result. - Exit(thread, *FP, *SP + 3, *pc); - NativeArguments args(thread, 2, *SP, *SP + 2); - if (!InvokeRuntime(thread, this, DRT_ReThrow, args)) { - return false; - } - UNREACHABLE(); - } - if (IsErrorClassId(result_cid)) { - // Unwind to entry frame. - fp_ = *FP; - pc_ = SavedCallerPC(fp_); - while (!IsEntryFrameMarker(pc_)) { - fp_ = SavedCallerFP(fp_); - pc_ = SavedCallerPC(fp_); - } - // Pop entry frame. - fp_ = SavedCallerFP(fp_); - special_[KernelBytecode::kExceptionSpecialIndex] = result; - return false; - } - } - return true; -} - -DART_FORCE_INLINE bool Interpreter::InvokeBytecode(Thread* thread, - FunctionPtr function, - ObjectPtr* call_base, - ObjectPtr* call_top, - const KBCInstr** pc, - ObjectPtr** FP, - ObjectPtr** SP) { - ASSERT(Function::HasBytecode(function)); -#if defined(DEBUG) - if (IsTracingExecution()) { - THR_Print("%" Pu64 " ", icount_); - THR_Print("invoking %s\n", - Function::Handle(function).ToFullyQualifiedCString()); - } -#endif - ObjectPtr* callee_fp = call_top + kKBCDartFrameFixedSize; - ASSERT(function == FrameFunction(callee_fp)); - BytecodePtr bytecode = function->ptr()->bytecode_; - callee_fp[kKBCPcMarkerSlotFromFp] = bytecode; - callee_fp[kKBCSavedCallerPcSlotFromFp] = - static_cast(reinterpret_cast(*pc)); - callee_fp[kKBCSavedCallerFpSlotFromFp] = - static_cast(reinterpret_cast(*FP)); - pp_ = bytecode->ptr()->object_pool_; - *pc = reinterpret_cast(bytecode->ptr()->instructions_); - NOT_IN_PRODUCT(pc_ = *pc); // For the profiler. - *FP = callee_fp; - NOT_IN_PRODUCT(fp_ = callee_fp); // For the profiler. - *SP = *FP - 1; - return true; -} - -DART_FORCE_INLINE bool Interpreter::Invoke(Thread* thread, - ObjectPtr* call_base, - ObjectPtr* call_top, - const KBCInstr** pc, - ObjectPtr** FP, - ObjectPtr** SP) { - ObjectPtr* callee_fp = call_top + kKBCDartFrameFixedSize; - FunctionPtr function = FrameFunction(callee_fp); - - for (;;) { - if (Function::HasCode(function)) { - return InvokeCompiled(thread, function, call_base, call_top, pc, FP, SP); - } - if (Function::HasBytecode(function)) { - return InvokeBytecode(thread, function, call_base, call_top, pc, FP, SP); - } - - // Compile the function to either generate code or load bytecode. - call_top[1] = 0; // Code result. - call_top[2] = function; - Exit(thread, *FP, call_top + 3, *pc); - NativeArguments native_args(thread, 1, call_top + 2, call_top + 1); - if (!InvokeRuntime(thread, this, DRT_CompileFunction, native_args)) { - return false; - } - // Reload objects after the call which may trigger GC. - function = Function::RawCast(call_top[2]); - - ASSERT(Function::HasCode(function) || Function::HasBytecode(function)); - } -} - -DART_FORCE_INLINE bool Interpreter::InstanceCall(Thread* thread, - StringPtr target_name, - ObjectPtr* call_base, - ObjectPtr* top, - const KBCInstr** pc, - ObjectPtr** FP, - ObjectPtr** SP) { - ObjectPtr null_value = Object::null(); - const intptr_t type_args_len = - InterpreterHelpers::ArgDescTypeArgsLen(argdesc_); - const intptr_t receiver_idx = type_args_len > 0 ? 1 : 0; - - intptr_t receiver_cid = - InterpreterHelpers::GetClassId(call_base[receiver_idx]); - - FunctionPtr target; - if (UNLIKELY(!lookup_cache_.Lookup(receiver_cid, target_name, argdesc_, - &target))) { - // Table lookup miss. - top[0] = null_value; // Clean up slot as it may be visited by GC. - top[1] = call_base[receiver_idx]; - top[2] = target_name; - top[3] = argdesc_; - top[4] = null_value; // Result slot. - - Exit(thread, *FP, top + 5, *pc); - NativeArguments native_args(thread, 3, /* argv */ top + 1, - /* result */ top + 4); - if (!InvokeRuntime(thread, this, DRT_InterpretedInstanceCallMissHandler, - native_args)) { - return false; - } - - target = static_cast(top[4]); - target_name = static_cast(top[2]); - argdesc_ = static_cast(top[3]); - } - - if (target != Function::null()) { - lookup_cache_.Insert(receiver_cid, target_name, argdesc_, target); - top[0] = target; - return Invoke(thread, call_base, top, pc, FP, SP); - } - - // The miss handler should only fail to return a function if lazy dispatchers - // are disabled, in which case we need to call DRT_InvokeNoSuchMethod, which - // walks the receiver appropriately in this case. - ASSERT(!FLAG_lazy_dispatchers); - - // The receiver, name, and argument descriptor are already in the appropriate - // places on the stack from the previous call. - ASSERT(top[4] == null_value); - - // Allocate array of arguments. - { - const intptr_t argc = - InterpreterHelpers::ArgDescArgCount(argdesc_) + receiver_idx; - ASSERT_EQUAL(top - call_base, argc); - - top[5] = Smi::New(argc); // length - top[6] = null_value; // type - Exit(thread, *FP, top + 7, *pc); - NativeArguments native_args(thread, 2, /* argv */ top + 5, - /* result */ top + 4); - if (!InvokeRuntime(thread, this, DRT_AllocateArray, native_args)) { - return false; - } - - // Copy arguments into the newly allocated array. - ArrayPtr array = Array::RawCast(top[4]); - for (intptr_t i = 0; i < argc; i++) { - array->ptr()->data()[i] = call_base[i]; - } - } - - { - Exit(thread, *FP, top + 5, *pc); - NativeArguments native_args(thread, 4, /* argv */ top + 1, - /* result */ top); - if (!InvokeRuntime(thread, this, DRT_InvokeNoSuchMethod, native_args)) { - return false; - } - - // Pop the call args and push the result. - ObjectPtr result = top[0]; - *SP = call_base; - **SP = result; - pp_ = InterpreterHelpers::FrameBytecode(*FP)->ptr()->object_pool_; - } - - return true; -} - -// Note: -// All macro helpers are intended to be used only inside Interpreter::Call. - -// Counts and prints executed bytecode instructions (in DEBUG mode). -#if defined(DEBUG) -#define TRACE_INSTRUCTION \ - if (IsTracingExecution()) { \ - TraceInstruction(pc); \ - } \ - if (IsWritingTraceFile()) { \ - WriteInstructionToTrace(pc); \ - } \ - icount_++; -#else -#define TRACE_INSTRUCTION -#endif // defined(DEBUG) - -// Decode opcode and A part of the given value and dispatch to the -// corresponding bytecode handler. -#ifdef DART_HAS_COMPUTED_GOTO -#define DISPATCH_OP(val) \ - do { \ - op = (val); \ - TRACE_INSTRUCTION \ - goto* dispatch[op]; \ - } while (0) -#else -#define DISPATCH_OP(val) \ - do { \ - op = (val); \ - TRACE_INSTRUCTION \ - goto SwitchDispatch; \ - } while (0) -#endif - -// Fetch next operation from PC and dispatch. -#define DISPATCH() DISPATCH_OP(*pc) - -// Load target of a jump instruction into PC. -#define LOAD_JUMP_TARGET() pc = rT - -#define BYTECODE_ENTRY_LABEL(Name) bc##Name: -#define BYTECODE_WIDE_ENTRY_LABEL(Name) bc##Name##_Wide: -#define BYTECODE_IMPL_LABEL(Name) bc##Name##Impl: -#define GOTO_BYTECODE_IMPL(Name) goto bc##Name##Impl; - -// Define entry point that handles bytecode Name with the given operand format. -#define BYTECODE(Name, Operands) BYTECODE_HEADER_##Operands(Name) - -// Helpers to decode common instruction formats. Used in conjunction with -// BYTECODE() macro. - -#define BYTECODE_HEADER_0(Name) \ - BYTECODE_ENTRY_LABEL(Name) \ - pc += 1; - -#define BYTECODE_HEADER_A(Name) \ - uint32_t rA; \ - USE(rA); \ - BYTECODE_ENTRY_LABEL(Name) \ - rA = pc[1]; \ - pc += 2; - -#define BYTECODE_HEADER_D(Name) \ - uint32_t rD; \ - USE(rD); \ - BYTECODE_WIDE_ENTRY_LABEL(Name) \ - rD = static_cast(pc[1]) | (static_cast(pc[2]) << 8) | \ - (static_cast(pc[3]) << 16) | \ - (static_cast(pc[4]) << 24); \ - pc += 5; \ - GOTO_BYTECODE_IMPL(Name); \ - BYTECODE_ENTRY_LABEL(Name) \ - rD = pc[1]; \ - pc += 2; \ - BYTECODE_IMPL_LABEL(Name) - -#define BYTECODE_HEADER_X(Name) \ - int32_t rX; \ - USE(rX); \ - BYTECODE_WIDE_ENTRY_LABEL(Name) \ - rX = static_cast(static_cast(pc[1]) | \ - (static_cast(pc[2]) << 8) | \ - (static_cast(pc[3]) << 16) | \ - (static_cast(pc[4]) << 24)); \ - pc += 5; \ - GOTO_BYTECODE_IMPL(Name); \ - BYTECODE_ENTRY_LABEL(Name) \ - rX = static_cast(pc[1]); \ - pc += 2; \ - BYTECODE_IMPL_LABEL(Name) - -#define BYTECODE_HEADER_T(Name) \ - const KBCInstr* rT; \ - USE(rT); \ - BYTECODE_WIDE_ENTRY_LABEL(Name) \ - rT = pc + (static_cast((static_cast(pc[1]) << 8) | \ - (static_cast(pc[2]) << 16) | \ - (static_cast(pc[3]) << 24)) >> \ - 8); \ - pc += 4; \ - GOTO_BYTECODE_IMPL(Name); \ - BYTECODE_ENTRY_LABEL(Name) \ - rT = pc + static_cast(pc[1]); \ - pc += 2; \ - BYTECODE_IMPL_LABEL(Name) - -#define BYTECODE_HEADER_A_E(Name) \ - uint32_t rA, rE; \ - USE(rA); \ - USE(rE); \ - BYTECODE_WIDE_ENTRY_LABEL(Name) \ - rA = pc[1]; \ - rE = static_cast(pc[2]) | (static_cast(pc[3]) << 8) | \ - (static_cast(pc[4]) << 16) | \ - (static_cast(pc[5]) << 24); \ - pc += 6; \ - GOTO_BYTECODE_IMPL(Name); \ - BYTECODE_ENTRY_LABEL(Name) \ - rA = pc[1]; \ - rE = pc[2]; \ - pc += 3; \ - BYTECODE_IMPL_LABEL(Name) - -#define BYTECODE_HEADER_A_Y(Name) \ - uint32_t rA; \ - int32_t rY; \ - USE(rA); \ - USE(rY); \ - BYTECODE_WIDE_ENTRY_LABEL(Name) \ - rA = pc[1]; \ - rY = static_cast(static_cast(pc[2]) | \ - (static_cast(pc[3]) << 8) | \ - (static_cast(pc[4]) << 16) | \ - (static_cast(pc[5]) << 24)); \ - pc += 6; \ - GOTO_BYTECODE_IMPL(Name); \ - BYTECODE_ENTRY_LABEL(Name) \ - rA = pc[1]; \ - rY = static_cast(pc[2]); \ - pc += 3; \ - BYTECODE_IMPL_LABEL(Name) - -#define BYTECODE_HEADER_D_F(Name) \ - uint32_t rD, rF; \ - USE(rD); \ - USE(rF); \ - BYTECODE_WIDE_ENTRY_LABEL(Name) \ - rD = static_cast(pc[1]) | (static_cast(pc[2]) << 8) | \ - (static_cast(pc[3]) << 16) | \ - (static_cast(pc[4]) << 24); \ - rF = pc[5]; \ - pc += 6; \ - GOTO_BYTECODE_IMPL(Name); \ - BYTECODE_ENTRY_LABEL(Name) \ - rD = pc[1]; \ - rF = pc[2]; \ - pc += 3; \ - BYTECODE_IMPL_LABEL(Name) - -#define BYTECODE_HEADER_A_B_C(Name) \ - uint32_t rA, rB, rC; \ - USE(rA); \ - USE(rB); \ - USE(rC); \ - BYTECODE_ENTRY_LABEL(Name) \ - rA = pc[1]; \ - rB = pc[2]; \ - rC = pc[3]; \ - pc += 4; - -#define HANDLE_EXCEPTION \ - do { \ - goto HandleException; \ - } while (0) - -#define HANDLE_RETURN \ - do { \ - pp_ = InterpreterHelpers::FrameBytecode(FP)->ptr()->object_pool_; \ - } while (0) - -// Runtime call helpers: handle invocation and potential exception after return. -#define INVOKE_RUNTIME(Func, Args) \ - if (!InvokeRuntime(thread, this, Func, Args)) { \ - HANDLE_EXCEPTION; \ - } else { \ - HANDLE_RETURN; \ - } - -#define INVOKE_NATIVE(Wrapper, Func, Args) \ - if (!InvokeNative(thread, this, Wrapper, Func, Args)) { \ - HANDLE_EXCEPTION; \ - } else { \ - HANDLE_RETURN; \ - } - -#define LOAD_CONSTANT(index) (pp_->ptr()->data()[(index)].raw_obj_) - -#define UNBOX_INT64(value, obj, selector) \ - int64_t value; \ - { \ - word raw_value = static_cast(obj); \ - if (LIKELY((raw_value & kSmiTagMask) == kSmiTag)) { \ - value = raw_value >> kSmiTagShift; \ - } else { \ - if (UNLIKELY(obj == null_value)) { \ - SP[0] = selector.raw(); \ - goto ThrowNullError; \ - } \ - value = Integer::GetInt64Value(RAW_CAST(Integer, obj)); \ - } \ - } - -#define BOX_INT64_RESULT(result) \ - if (LIKELY(Smi::IsValid(result))) { \ - SP[0] = Smi::New(static_cast(result)); \ - } else if (!AllocateMint(thread, result, pc, FP, SP)) { \ - HANDLE_EXCEPTION; \ - } \ - ASSERT(Integer::GetInt64Value(RAW_CAST(Integer, SP[0])) == result); - -#define UNBOX_DOUBLE(value, obj, selector) \ - double value; \ - { \ - if (UNLIKELY(obj == null_value)) { \ - SP[0] = selector.raw(); \ - goto ThrowNullError; \ - } \ - value = Double::RawCast(obj)->ptr()->value_; \ - } - -#define BOX_DOUBLE_RESULT(result) \ - if (!AllocateDouble(thread, result, pc, FP, SP)) { \ - HANDLE_EXCEPTION; \ - } \ - ASSERT(Utils::DoublesBitEqual(Double::RawCast(SP[0])->ptr()->value_, result)); - -#define BUMP_USAGE_COUNTER_ON_ENTRY(function) \ - { \ - int32_t counter = ++(function->ptr()->usage_counter_); \ - if (UNLIKELY(FLAG_compilation_counter_threshold >= 0 && \ - counter >= FLAG_compilation_counter_threshold && \ - !Function::HasCode(function))) { \ - SP[1] = 0; /* Unused result. */ \ - SP[2] = function; \ - Exit(thread, FP, SP + 3, pc); \ - INVOKE_RUNTIME(DRT_CompileInterpretedFunction, \ - NativeArguments(thread, 1, SP + 2, SP + 1)); \ - function = FrameFunction(FP); \ - } \ - } - -#ifdef PRODUCT -#define DEBUG_CHECK -#else -// The DEBUG_CHECK macro must only be called from bytecodes listed in -// KernelBytecode::IsDebugCheckedOpcode. -#define DEBUG_CHECK \ - if (is_debugging()) { \ - /* Check for debug breakpoint or if single stepping. */ \ - if (thread->isolate()->debugger()->HasBytecodeBreakpointAt(pc)) { \ - SP[1] = null_value; \ - Exit(thread, FP, SP + 2, pc); \ - INVOKE_RUNTIME(DRT_BreakpointRuntimeHandler, \ - NativeArguments(thread, 0, nullptr, SP + 1)) \ - } \ - /* The debugger expects to see the same pc again when single-stepping */ \ - if (thread->isolate()->single_step()) { \ - Exit(thread, FP, SP + 1, pc); \ - INVOKE_RUNTIME(DRT_SingleStepHandler, \ - NativeArguments(thread, 0, nullptr, nullptr)); \ - } \ - } -#endif // PRODUCT - -bool Interpreter::CopyParameters(Thread* thread, - const KBCInstr** pc, - ObjectPtr** FP, - ObjectPtr** SP, - const intptr_t num_fixed_params, - const intptr_t num_opt_pos_params, - const intptr_t num_opt_named_params) { - const intptr_t min_num_pos_args = num_fixed_params; - const intptr_t max_num_pos_args = num_fixed_params + num_opt_pos_params; - - // Decode arguments descriptor. - const intptr_t arg_count = InterpreterHelpers::ArgDescArgCount(argdesc_); - const intptr_t pos_count = InterpreterHelpers::ArgDescPosCount(argdesc_); - const intptr_t named_count = (arg_count - pos_count); - - // Check that got the right number of positional parameters. - if ((min_num_pos_args > pos_count) || (pos_count > max_num_pos_args)) { - return false; - } - - // Copy all passed position arguments. - ObjectPtr* first_arg = FrameArguments(*FP, arg_count); - memmove(*FP, first_arg, pos_count * kWordSize); - - if (num_opt_named_params != 0) { - // This is a function with named parameters. - // Walk the list of named parameters and their - // default values encoded as pairs of LoadConstant instructions that - // follows the entry point and find matching values via arguments - // descriptor. - ObjectPtr* argdesc_data = argdesc_->ptr()->data(); - - intptr_t i = 0; // argument position - intptr_t j = 0; // parameter position - while ((j < num_opt_named_params) && (i < named_count)) { - // Fetch formal parameter information: name, default value, target slot. - const KBCInstr* load_name = *pc; - const KBCInstr* load_value = KernelBytecode::Next(load_name); - *pc = KernelBytecode::Next(load_value); - ASSERT(KernelBytecode::IsLoadConstantOpcode(load_name)); - ASSERT(KernelBytecode::IsLoadConstantOpcode(load_value)); - const uint8_t reg = KernelBytecode::DecodeA(load_name); - ASSERT(reg == KernelBytecode::DecodeA(load_value)); - - StringPtr name = static_cast( - LOAD_CONSTANT(KernelBytecode::DecodeE(load_name))); - if (name == argdesc_data[ArgumentsDescriptor::name_index(i)]) { - // Parameter was passed. Fetch passed value. - const intptr_t arg_index = Smi::Value(static_cast( - argdesc_data[ArgumentsDescriptor::position_index(i)])); - (*FP)[reg] = first_arg[arg_index]; - ++i; // Consume passed argument. - } else { - // Parameter was not passed. Fetch default value. - (*FP)[reg] = LOAD_CONSTANT(KernelBytecode::DecodeE(load_value)); - } - ++j; // Next formal parameter. - } - - // If we have unprocessed formal parameters then initialize them all - // using default values. - while (j < num_opt_named_params) { - const KBCInstr* load_name = *pc; - const KBCInstr* load_value = KernelBytecode::Next(load_name); - *pc = KernelBytecode::Next(load_value); - ASSERT(KernelBytecode::IsLoadConstantOpcode(load_name)); - ASSERT(KernelBytecode::IsLoadConstantOpcode(load_value)); - const uint8_t reg = KernelBytecode::DecodeA(load_name); - ASSERT(reg == KernelBytecode::DecodeA(load_value)); - - (*FP)[reg] = LOAD_CONSTANT(KernelBytecode::DecodeE(load_value)); - ++j; - } - - // If we have unprocessed passed arguments that means we have mismatch - // between formal parameters and concrete arguments. This can only - // occur if the current function is a closure. - if (i < named_count) { - return false; - } - - // SP points past copied arguments. - *SP = *FP + num_fixed_params + num_opt_named_params - 1; - } else { - ASSERT(num_opt_pos_params != 0); - if (named_count != 0) { - // Function can't have both named and optional positional parameters. - // This kind of mismatch can only occur if the current function - // is a closure. - return false; - } - - // Process the list of default values encoded as a sequence of - // LoadConstant instructions after EntryOpt bytecode. - // Execute only those that correspond to parameters that were not passed. - for (intptr_t i = num_fixed_params; i < pos_count; ++i) { - ASSERT(KernelBytecode::IsLoadConstantOpcode(*pc)); - *pc = KernelBytecode::Next(*pc); - } - for (intptr_t i = pos_count; i < max_num_pos_args; ++i) { - const KBCInstr* load_value = *pc; - *pc = KernelBytecode::Next(load_value); - ASSERT(KernelBytecode::IsLoadConstantOpcode(load_value)); - ASSERT(KernelBytecode::DecodeA(load_value) == i); - (*FP)[i] = LOAD_CONSTANT(KernelBytecode::DecodeE(load_value)); - } - - // SP points past the last copied parameter. - *SP = *FP + max_num_pos_args - 1; - } - - return true; -} - -bool Interpreter::AssertAssignable(Thread* thread, - const KBCInstr* pc, - ObjectPtr* FP, - ObjectPtr* call_top, - ObjectPtr* args, - SubtypeTestCachePtr cache) { - ObjectPtr null_value = Object::null(); - if (cache != null_value) { - InstancePtr instance = static_cast(args[0]); - TypeArgumentsPtr instantiator_type_arguments = - static_cast(args[2]); - TypeArgumentsPtr function_type_arguments = - static_cast(args[3]); - - const intptr_t cid = InterpreterHelpers::GetClassId(instance); - - TypeArgumentsPtr instance_type_arguments = - static_cast(null_value); - ObjectPtr instance_cid_or_function; - - TypeArgumentsPtr parent_function_type_arguments; - TypeArgumentsPtr delayed_function_type_arguments; - if (cid == kClosureCid) { - ClosurePtr closure = static_cast(instance); - instance_type_arguments = closure->ptr()->instantiator_type_arguments_; - parent_function_type_arguments = closure->ptr()->function_type_arguments_; - delayed_function_type_arguments = closure->ptr()->delayed_type_arguments_; - instance_cid_or_function = closure->ptr()->function_; - } else { - instance_cid_or_function = Smi::New(cid); - - ClassPtr instance_class = thread->isolate()->class_table()->At(cid); - if (instance_class->ptr()->num_type_arguments_ < 0) { - goto AssertAssignableCallRuntime; - } else if (instance_class->ptr()->num_type_arguments_ > 0) { - instance_type_arguments = reinterpret_cast( - instance->ptr())[instance_class->ptr() - ->host_type_arguments_field_offset_in_words_]; - } - parent_function_type_arguments = - static_cast(null_value); - delayed_function_type_arguments = - static_cast(null_value); - } - - for (ObjectPtr* entries = cache->ptr()->cache_->ptr()->data(); - entries[0] != null_value; - entries += SubtypeTestCache::kTestEntryLength) { - if ((entries[SubtypeTestCache::kInstanceClassIdOrFunction] == - instance_cid_or_function) && - (entries[SubtypeTestCache::kInstanceTypeArguments] == - instance_type_arguments) && - (entries[SubtypeTestCache::kInstantiatorTypeArguments] == - instantiator_type_arguments) && - (entries[SubtypeTestCache::kFunctionTypeArguments] == - function_type_arguments) && - (entries[SubtypeTestCache::kInstanceParentFunctionTypeArguments] == - parent_function_type_arguments) && - (entries[SubtypeTestCache::kInstanceDelayedFunctionTypeArguments] == - delayed_function_type_arguments)) { - if (Bool::True().raw() == entries[SubtypeTestCache::kTestResult]) { - return true; - } else { - break; - } - } - } - } - -AssertAssignableCallRuntime: - // args[0]: Instance. - // args[1]: Type. - // args[2]: Instantiator type args. - // args[3]: Function type args. - // args[4]: Name. - args[5] = cache; - args[6] = Smi::New(kTypeCheckFromInline); - args[7] = 0; // Unused result. - Exit(thread, FP, args + 8, pc); - NativeArguments native_args(thread, 7, args, args + 7); - return InvokeRuntime(thread, this, DRT_TypeCheck, native_args); -} - -template -bool Interpreter::AssertAssignableField(Thread* thread, - const KBCInstr* pc, - ObjectPtr* FP, - ObjectPtr* SP, - InstancePtr instance, - FieldPtr field, - InstancePtr value) { - AbstractTypePtr field_type = field->ptr()->type_; - // Perform type test of value if field type is not one of dynamic, object, - // or void, and if the value is not null. - if (field_type->GetClassId() == kTypeCid) { - classid_t cid = Smi::Value( - static_cast(Type::RawCast(field_type)->ptr()->type_class_id_)); - // TODO(regis): Revisit shortcut for NNBD. - if (cid == kDynamicCid || cid == kInstanceCid || cid == kVoidCid) { - return true; - } - } - ObjectPtr null_value = Object::null(); - if (value == null_value) { - // TODO(regis): Revisit null shortcut for NNBD. - return true; - } - - SubtypeTestCachePtr cache = field->ptr()->type_test_cache_; - if (UNLIKELY(cache == null_value)) { - // Allocate new cache. - SP[1] = instance; // Preserve. - SP[2] = field; // Preserve. - SP[3] = value; // Preserve. - SP[4] = null_value; // Result slot. - - Exit(thread, FP, SP + 5, pc); - if (!InvokeRuntime(thread, this, DRT_AllocateSubtypeTestCache, - NativeArguments(thread, 0, /* argv */ SP + 4, - /* retval */ SP + 4))) { - return false; - } - - // Reload objects after the call which may trigger GC. - instance = static_cast(SP[1]); - field = static_cast(SP[2]); - value = static_cast(SP[3]); - cache = static_cast(SP[4]); - field_type = field->ptr()->type_; - field->ptr()->type_test_cache_ = cache; - } - - // Push arguments of type test. - SP[1] = value; - SP[2] = field_type; - // Provide type arguments of instance as instantiator. - SP[3] = InterpreterHelpers::GetTypeArguments(thread, instance); - SP[4] = null_value; // Implicit setters cannot be generic. - SP[5] = is_getter ? Symbols::FunctionResult().raw() : field->ptr()->name_; - return AssertAssignable(thread, pc, FP, /* call_top */ SP + 5, - /* args */ SP + 1, cache); -} - -ObjectPtr Interpreter::Call(const Function& function, - const Array& arguments_descriptor, - const Array& arguments, - Thread* thread) { - return Call(function.raw(), arguments_descriptor.raw(), arguments.Length(), - arguments.raw_ptr()->data(), thread); -} - -// Allocate a _Mint for the given int64_t value and puts it into SP[0]. -// Returns false on exception. -DART_NOINLINE bool Interpreter::AllocateMint(Thread* thread, - int64_t value, - const KBCInstr* pc, - ObjectPtr* FP, - ObjectPtr* SP) { - ASSERT(!Smi::IsValid(value)); - MintPtr result; - if (TryAllocate(thread, kMintCid, Mint::InstanceSize(), - reinterpret_cast(&result))) { - result->ptr()->value_ = value; - SP[0] = result; - return true; - } else { - SP[0] = 0; // Space for the result. - SP[1] = thread->isolate()->object_store()->mint_class(); // Class object. - SP[2] = Object::null(); // Type arguments. - Exit(thread, FP, SP + 3, pc); - NativeArguments args(thread, 2, SP + 1, SP); - if (!InvokeRuntime(thread, this, DRT_AllocateObject, args)) { - return false; - } - static_cast(SP[0])->ptr()->value_ = value; - return true; - } -} - -// Allocate a _Double for the given double value and put it into SP[0]. -// Returns false on exception. -DART_NOINLINE bool Interpreter::AllocateDouble(Thread* thread, - double value, - const KBCInstr* pc, - ObjectPtr* FP, - ObjectPtr* SP) { - DoublePtr result; - if (TryAllocate(thread, kDoubleCid, Double::InstanceSize(), - reinterpret_cast(&result))) { - result->ptr()->value_ = value; - SP[0] = result; - return true; - } else { - SP[0] = 0; // Space for the result. - SP[1] = thread->isolate()->object_store()->double_class(); - SP[2] = Object::null(); // Type arguments. - Exit(thread, FP, SP + 3, pc); - NativeArguments args(thread, 2, SP + 1, SP); - if (!InvokeRuntime(thread, this, DRT_AllocateObject, args)) { - return false; - } - Double::RawCast(SP[0])->ptr()->value_ = value; - return true; - } -} - -// Allocate a _Float32x4 for the given simd value and put it into SP[0]. -// Returns false on exception. -DART_NOINLINE bool Interpreter::AllocateFloat32x4(Thread* thread, - simd128_value_t value, - const KBCInstr* pc, - ObjectPtr* FP, - ObjectPtr* SP) { - Float32x4Ptr result; - if (TryAllocate(thread, kFloat32x4Cid, Float32x4::InstanceSize(), - reinterpret_cast(&result))) { - value.writeTo(result->ptr()->value_); - SP[0] = result; - return true; - } else { - SP[0] = 0; // Space for the result. - SP[1] = thread->isolate()->object_store()->float32x4_class(); - SP[2] = Object::null(); // Type arguments. - Exit(thread, FP, SP + 3, pc); - NativeArguments args(thread, 2, SP + 1, SP); - if (!InvokeRuntime(thread, this, DRT_AllocateObject, args)) { - return false; - } - value.writeTo(Float32x4::RawCast(SP[0])->ptr()->value_); - return true; - } -} - -// Allocate _Float64x2 box for the given simd value and put it into SP[0]. -// Returns false on exception. -DART_NOINLINE bool Interpreter::AllocateFloat64x2(Thread* thread, - simd128_value_t value, - const KBCInstr* pc, - ObjectPtr* FP, - ObjectPtr* SP) { - Float64x2Ptr result; - if (TryAllocate(thread, kFloat64x2Cid, Float64x2::InstanceSize(), - reinterpret_cast(&result))) { - value.writeTo(result->ptr()->value_); - SP[0] = result; - return true; - } else { - SP[0] = 0; // Space for the result. - SP[1] = thread->isolate()->object_store()->float64x2_class(); - SP[2] = Object::null(); // Type arguments. - Exit(thread, FP, SP + 3, pc); - NativeArguments args(thread, 2, SP + 1, SP); - if (!InvokeRuntime(thread, this, DRT_AllocateObject, args)) { - return false; - } - value.writeTo(Float64x2::RawCast(SP[0])->ptr()->value_); - return true; - } -} - -// Allocate a _List with the given type arguments and length and put it into -// SP[0]. Returns false on exception. -bool Interpreter::AllocateArray(Thread* thread, - TypeArgumentsPtr type_args, - ObjectPtr length_object, - const KBCInstr* pc, - ObjectPtr* FP, - ObjectPtr* SP) { - if (LIKELY(!length_object->IsHeapObject())) { - const intptr_t length = Smi::Value(Smi::RawCast(length_object)); - if (LIKELY(Array::IsValidLength(length))) { - ArrayPtr result; - if (TryAllocate(thread, kArrayCid, Array::InstanceSize(length), - reinterpret_cast(&result))) { - result->ptr()->type_arguments_ = type_args; - result->ptr()->length_ = Smi::New(length); - for (intptr_t i = 0; i < length; i++) { - result->ptr()->data()[i] = Object::null(); - } - SP[0] = result; - return true; - } - } - } - - SP[0] = 0; // Space for the result; - SP[1] = length_object; - SP[2] = type_args; - Exit(thread, FP, SP + 3, pc); - NativeArguments args(thread, 2, SP + 1, SP); - return InvokeRuntime(thread, this, DRT_AllocateArray, args); -} - -// Allocate a _Context with the given length and put it into SP[0]. -// Returns false on exception. -bool Interpreter::AllocateContext(Thread* thread, - intptr_t num_context_variables, - const KBCInstr* pc, - ObjectPtr* FP, - ObjectPtr* SP) { - ContextPtr result; - if (TryAllocate(thread, kContextCid, - Context::InstanceSize(num_context_variables), - reinterpret_cast(&result))) { - result->ptr()->num_variables_ = num_context_variables; - ObjectPtr null_value = Object::null(); - result->ptr()->parent_ = static_cast(null_value); - for (intptr_t i = 0; i < num_context_variables; i++) { - result->ptr()->data()[i] = null_value; - } - SP[0] = result; - return true; - } else { - SP[0] = 0; // Space for the result. - SP[1] = Smi::New(num_context_variables); - Exit(thread, FP, SP + 2, pc); - NativeArguments args(thread, 1, SP + 1, SP); - return InvokeRuntime(thread, this, DRT_AllocateContext, args); - } -} - -// Allocate a _Closure and put it into SP[0]. -// Returns false on exception. -bool Interpreter::AllocateClosure(Thread* thread, - const KBCInstr* pc, - ObjectPtr* FP, - ObjectPtr* SP) { - const intptr_t instance_size = Closure::InstanceSize(); - ClosurePtr result; - if (TryAllocate(thread, kClosureCid, instance_size, - reinterpret_cast(&result))) { - uword start = ObjectLayout::ToAddr(result); - ObjectPtr null_value = Object::null(); - for (intptr_t offset = sizeof(InstanceLayout); offset < instance_size; - offset += kWordSize) { - *reinterpret_cast(start + offset) = null_value; - } - SP[0] = result; - return true; - } else { - SP[0] = 0; // Space for the result. - SP[1] = thread->isolate()->object_store()->closure_class(); - SP[2] = Object::null(); // Type arguments. - Exit(thread, FP, SP + 3, pc); - NativeArguments args(thread, 2, SP + 1, SP); - return InvokeRuntime(thread, this, DRT_AllocateObject, args); - } -} - -ObjectPtr Interpreter::Call(FunctionPtr function, - ArrayPtr argdesc, - intptr_t argc, - ObjectPtr const* argv, - Thread* thread) { - // Interpreter state (see constants_kbc.h for high-level overview). - const KBCInstr* pc; // Program Counter: points to the next op to execute. - ObjectPtr* FP; // Frame Pointer. - ObjectPtr* SP; // Stack Pointer. - - uint32_t op; // Currently executing op. - - bool reentering = fp_ != NULL; - if (!reentering) { - fp_ = reinterpret_cast(stack_base_); - } -#if defined(DEBUG) - if (IsTracingExecution()) { - THR_Print("%" Pu64 " ", icount_); - THR_Print("%s interpreter 0x%" Px " at fp_ 0x%" Px " exit 0x%" Px " %s\n", - reentering ? "Re-entering" : "Entering", - reinterpret_cast(this), reinterpret_cast(fp_), - thread->top_exit_frame_info(), - Function::Handle(function).ToFullyQualifiedCString()); - } -#endif - - // Setup entry frame: - // - // ^ - // | previous Dart frames - // | - // | ........... | -+ - // fp_ > | exit fp_ | saved top_exit_frame_info - // | argdesc_ | saved argdesc_ (for reentering interpreter) - // | pp_ | saved pp_ (for reentering interpreter) - // | arg 0 | -+ - // | arg 1 | | - // ... | - // > incoming arguments - // | - // | arg argc-1 | -+ - // | function | -+ - // | code | | - // | caller PC | ---> special fake PC marking an entry frame - // SP > | fp_ | | - // FP > | ........... | > normal Dart frame (see stack_frame_kbc.h) - // | - // v - // - // A negative argc indicates reverse memory order of arguments. - const intptr_t arg_count = argc < 0 ? -argc : argc; - FP = fp_ + kKBCEntrySavedSlots + arg_count + kKBCDartFrameFixedSize; - SP = FP - 1; - - // Save outer top_exit_frame_info, current argdesc, and current pp. - fp_[kKBCExitLinkSlotFromEntryFp] = - static_cast(thread->top_exit_frame_info()); - thread->set_top_exit_frame_info(0); - fp_[kKBCSavedArgDescSlotFromEntryFp] = static_cast(argdesc_); - fp_[kKBCSavedPpSlotFromEntryFp] = static_cast(pp_); - - // Copy arguments and setup the Dart frame. - for (intptr_t i = 0; i < arg_count; i++) { - fp_[kKBCEntrySavedSlots + i] = argv[argc < 0 ? -i : i]; - } - - BytecodePtr bytecode = function->ptr()->bytecode_; - FP[kKBCFunctionSlotFromFp] = function; - FP[kKBCPcMarkerSlotFromFp] = bytecode; - FP[kKBCSavedCallerPcSlotFromFp] = static_cast(kEntryFramePcMarker); - FP[kKBCSavedCallerFpSlotFromFp] = - static_cast(reinterpret_cast(fp_)); - - // Load argument descriptor. - argdesc_ = argdesc; - - // Ready to start executing bytecode. Load entry point and corresponding - // object pool. - pc = reinterpret_cast(bytecode->ptr()->instructions_); - NOT_IN_PRODUCT(pc_ = pc); // For the profiler. - NOT_IN_PRODUCT(fp_ = FP); // For the profiler. - pp_ = bytecode->ptr()->object_pool_; - - // Save current VM tag and mark thread as executing Dart code. For the - // profiler, do this *after* setting up the entry frame (compare the machine - // code entry stubs). - const uword vm_tag = thread->vm_tag(); - thread->set_vm_tag(VMTag::kDartInterpretedTagId); - - // Save current top stack resource and reset the list. - StackResource* top_resource = thread->top_resource(); - thread->set_top_resource(NULL); - - // Cache some frequently used values in the frame. - BoolPtr true_value = Bool::True().raw(); - BoolPtr false_value = Bool::False().raw(); - ObjectPtr null_value = Object::null(); - -#ifdef DART_HAS_COMPUTED_GOTO - static const void* dispatch[] = { -#define TARGET(name, fmt, kind, fmta, fmtb, fmtc) &&bc##name, - KERNEL_BYTECODES_LIST(TARGET) -#undef TARGET - }; - DISPATCH(); // Enter the dispatch loop. -#else - DISPATCH(); // Enter the dispatch loop. -SwitchDispatch: - switch (op & 0xFF) { -#define TARGET(name, fmt, kind, fmta, fmtb, fmtc) \ - case KernelBytecode::k##name: \ - goto bc##name; - KERNEL_BYTECODES_LIST(TARGET) -#undef TARGET - default: - FATAL1("Undefined opcode: %d\n", op); - } -#endif - - // KernelBytecode handlers (see constants_kbc.h for bytecode descriptions). - { - BYTECODE(Entry, D); - const intptr_t num_locals = rD; - - // Initialize locals with null & set SP. - for (intptr_t i = 0; i < num_locals; i++) { - FP[i] = null_value; - } - SP = FP + num_locals - 1; - - DISPATCH(); - } - - { - BYTECODE(EntryFixed, A_E); - const intptr_t num_fixed_params = rA; - const intptr_t num_locals = rE; - - const intptr_t arg_count = InterpreterHelpers::ArgDescArgCount(argdesc_); - const intptr_t pos_count = InterpreterHelpers::ArgDescPosCount(argdesc_); - if ((arg_count != num_fixed_params) || (pos_count != num_fixed_params)) { - SP[1] = FrameFunction(FP); - goto NoSuchMethodFromPrologue; - } - - // Initialize locals with null & set SP. - for (intptr_t i = 0; i < num_locals; i++) { - FP[i] = null_value; - } - SP = FP + num_locals - 1; - - DISPATCH(); - } - - { - BYTECODE(EntryOptional, A_B_C); - if (CopyParameters(thread, &pc, &FP, &SP, rA, rB, rC)) { - DISPATCH(); - } else { - SP[1] = FrameFunction(FP); - goto NoSuchMethodFromPrologue; - } - } - - { - BYTECODE(Frame, D); - // Initialize locals with null and increment SP. - const intptr_t num_locals = rD; - for (intptr_t i = 1; i <= num_locals; i++) { - SP[i] = null_value; - } - SP += num_locals; - - DISPATCH(); - } - - { - BYTECODE(SetFrame, A); - SP = FP + rA - 1; - DISPATCH(); - } - - { - BYTECODE(CheckStack, A); - { - // Check the interpreter's own stack limit for actual interpreter's stack - // overflows, and also the thread's stack limit for scheduled interrupts. - if (reinterpret_cast(SP) >= overflow_stack_limit() || - thread->HasScheduledInterrupts()) { - Exit(thread, FP, SP + 1, pc); - INVOKE_RUNTIME(DRT_StackOverflow, - NativeArguments(thread, 0, nullptr, nullptr)); - } - } - FunctionPtr function = FrameFunction(FP); - int32_t counter = ++(function->ptr()->usage_counter_); - if (UNLIKELY(FLAG_compilation_counter_threshold >= 0 && - counter >= FLAG_compilation_counter_threshold && - !Function::HasCode(function))) { - SP[1] = 0; // Unused result. - SP[2] = function; - Exit(thread, FP, SP + 3, pc); - INVOKE_RUNTIME(DRT_CompileInterpretedFunction, - NativeArguments(thread, 1, SP + 2, SP + 1)); - } - DISPATCH(); - } - - { - BYTECODE(DebugCheck, 0); - DEBUG_CHECK; - DISPATCH(); - } - - { - BYTECODE(CheckFunctionTypeArgs, A_E); - const intptr_t declared_type_args_len = rA; - const intptr_t first_stack_local_index = rE; - - // Decode arguments descriptor's type args len. - const intptr_t type_args_len = - InterpreterHelpers::ArgDescTypeArgsLen(argdesc_); - if ((type_args_len != declared_type_args_len) && (type_args_len != 0)) { - SP[1] = FrameFunction(FP); - goto NoSuchMethodFromPrologue; - } - if (type_args_len > 0) { - // Decode arguments descriptor's argument count (excluding type args). - const intptr_t arg_count = InterpreterHelpers::ArgDescArgCount(argdesc_); - // Copy passed-in type args to first local slot. - FP[first_stack_local_index] = *FrameArguments(FP, arg_count + 1); - } else if (declared_type_args_len > 0) { - FP[first_stack_local_index] = Object::null(); - } - DISPATCH(); - } - - { - BYTECODE(InstantiateType, D); - // Stack: instantiator type args, function type args - ObjectPtr type = LOAD_CONSTANT(rD); - SP[1] = type; - SP[2] = SP[-1]; - SP[3] = SP[0]; - Exit(thread, FP, SP + 4, pc); - { - INVOKE_RUNTIME(DRT_InstantiateType, - NativeArguments(thread, 3, SP + 1, SP - 1)); - } - SP -= 1; - DISPATCH(); - } - - { - BYTECODE(InstantiateTypeArgumentsTOS, A_E); - // Stack: instantiator type args, function type args - TypeArgumentsPtr type_arguments = - static_cast(LOAD_CONSTANT(rE)); - - ObjectPtr instantiator_type_args = SP[-1]; - ObjectPtr function_type_args = SP[0]; - // If both instantiators are null and if the type argument vector - // instantiated from null becomes a vector of dynamic, then use null as - // the type arguments. - if ((rA == 0) || (null_value != instantiator_type_args) || - (null_value != function_type_args)) { - // First lookup in the cache. - ArrayPtr instantiations = type_arguments->ptr()->instantiations_; - for (intptr_t i = 0; - instantiations->ptr()->data()[i] != - static_cast(TypeArguments::kNoInstantiator); - i += TypeArguments::Instantiation::kSizeInWords) { - if ((instantiations->ptr()->data() - [i + - TypeArguments::Instantiation::kInstantiatorTypeArgsIndex] == - instantiator_type_args) && - (instantiations->ptr()->data() - [i + TypeArguments::Instantiation::kFunctionTypeArgsIndex] == - function_type_args)) { - // Found in the cache. - SP[-1] = - instantiations->ptr()->data()[i + TypeArguments::Instantiation:: - kInstantiatedTypeArgsIndex]; - goto InstantiateTypeArgumentsTOSDone; - } - } - - // Cache lookup failed, call runtime. - SP[1] = type_arguments; - SP[2] = instantiator_type_args; - SP[3] = function_type_args; - - Exit(thread, FP, SP + 4, pc); - INVOKE_RUNTIME(DRT_InstantiateTypeArguments, - NativeArguments(thread, 3, SP + 1, SP - 1)); - } - - InstantiateTypeArgumentsTOSDone: - SP -= 1; - DISPATCH(); - } - - { - BYTECODE(Throw, A); - { - SP[1] = 0; // Space for result. - Exit(thread, FP, SP + 2, pc); - if (rA == 0) { // Throw - INVOKE_RUNTIME(DRT_Throw, NativeArguments(thread, 1, SP, SP + 1)); - } else { // ReThrow - INVOKE_RUNTIME(DRT_ReThrow, NativeArguments(thread, 2, SP - 1, SP + 1)); - } - } - DISPATCH(); - } - - { - BYTECODE(Drop1, 0); - SP--; - DISPATCH(); - } - - { - BYTECODE(LoadConstant, A_E); - FP[rA] = LOAD_CONSTANT(rE); - DISPATCH(); - } - - { - BYTECODE(PushConstant, D); - *++SP = LOAD_CONSTANT(rD); - DISPATCH(); - } - - { - BYTECODE(PushNull, 0); - *++SP = null_value; - DISPATCH(); - } - - { - BYTECODE(PushTrue, 0); - *++SP = true_value; - DISPATCH(); - } - - { - BYTECODE(PushFalse, 0); - *++SP = false_value; - DISPATCH(); - } - - { - BYTECODE(PushInt, X); - *++SP = Smi::New(rX); - DISPATCH(); - } - - { - BYTECODE(Push, X); - *++SP = FP[rX]; - DISPATCH(); - } - - { - BYTECODE(StoreLocal, X); - FP[rX] = *SP; - DISPATCH(); - } - - { - BYTECODE(PopLocal, X); - FP[rX] = *SP--; - DISPATCH(); - } - - { - BYTECODE(MoveSpecial, A_Y); - ASSERT(rA < KernelBytecode::kSpecialIndexCount); - FP[rY] = special_[rA]; - DISPATCH(); - } - - { - BYTECODE(BooleanNegateTOS, 0); - SP[0] = (SP[0] == true_value) ? false_value : true_value; - DISPATCH(); - } - - { - BYTECODE(DirectCall, D_F); - DEBUG_CHECK; - // Invoke target function. - { - const uint32_t argc = rF; - const uint32_t kidx = rD; - - InterpreterHelpers::IncrementUsageCounter(FrameFunction(FP)); - *++SP = LOAD_CONSTANT(kidx); - ObjectPtr* call_base = SP - argc; - ObjectPtr* call_top = SP; - argdesc_ = static_cast(LOAD_CONSTANT(kidx + 1)); - if (!Invoke(thread, call_base, call_top, &pc, &FP, &SP)) { - HANDLE_EXCEPTION; - } - } - - DISPATCH(); - } - - { - BYTECODE(UncheckedDirectCall, D_F); - DEBUG_CHECK; - // Invoke target function. - { - const uint32_t argc = rF; - const uint32_t kidx = rD; - - InterpreterHelpers::IncrementUsageCounter(FrameFunction(FP)); - *++SP = LOAD_CONSTANT(kidx); - ObjectPtr* call_base = SP - argc; - ObjectPtr* call_top = SP; - argdesc_ = static_cast(LOAD_CONSTANT(kidx + 1)); - if (!Invoke(thread, call_base, call_top, &pc, &FP, &SP)) { - HANDLE_EXCEPTION; - } - } - - DISPATCH(); - } - - { - BYTECODE(InterfaceCall, D_F); - DEBUG_CHECK; - { - const uint32_t argc = rF; - const uint32_t kidx = rD; - - ObjectPtr* call_base = SP - argc + 1; - ObjectPtr* call_top = SP + 1; - - InterpreterHelpers::IncrementUsageCounter(FrameFunction(FP)); - StringPtr target_name = - static_cast(LOAD_CONSTANT(kidx))->ptr()->name_; - argdesc_ = static_cast(LOAD_CONSTANT(kidx + 1)); - if (!InstanceCall(thread, target_name, call_base, call_top, &pc, &FP, - &SP)) { - HANDLE_EXCEPTION; - } - } - - DISPATCH(); - } - { - BYTECODE(InstantiatedInterfaceCall, D_F); - DEBUG_CHECK; - { - const uint32_t argc = rF; - const uint32_t kidx = rD; - - ObjectPtr* call_base = SP - argc + 1; - ObjectPtr* call_top = SP + 1; - - InterpreterHelpers::IncrementUsageCounter(FrameFunction(FP)); - StringPtr target_name = - static_cast(LOAD_CONSTANT(kidx))->ptr()->name_; - argdesc_ = static_cast(LOAD_CONSTANT(kidx + 1)); - if (!InstanceCall(thread, target_name, call_base, call_top, &pc, &FP, - &SP)) { - HANDLE_EXCEPTION; - } - } - - DISPATCH(); - } - - { - BYTECODE(UncheckedClosureCall, D_F); - DEBUG_CHECK; - { - const uint32_t argc = rF; - const uint32_t kidx = rD; - - ClosurePtr receiver = Closure::RawCast(*SP--); - ObjectPtr* call_base = SP - argc + 1; - ObjectPtr* call_top = SP + 1; - - InterpreterHelpers::IncrementUsageCounter(FrameFunction(FP)); - if (UNLIKELY(receiver == null_value)) { - SP[0] = Symbols::Call().raw(); - goto ThrowNullError; - } - argdesc_ = static_cast(LOAD_CONSTANT(kidx)); - call_top[0] = receiver->ptr()->function_; - - if (!Invoke(thread, call_base, call_top, &pc, &FP, &SP)) { - HANDLE_EXCEPTION; - } - } - - DISPATCH(); - } - - { - BYTECODE(UncheckedInterfaceCall, D_F); - DEBUG_CHECK; - { - const uint32_t argc = rF; - const uint32_t kidx = rD; - - ObjectPtr* call_base = SP - argc + 1; - ObjectPtr* call_top = SP + 1; - - InterpreterHelpers::IncrementUsageCounter(FrameFunction(FP)); - StringPtr target_name = - static_cast(LOAD_CONSTANT(kidx))->ptr()->name_; - argdesc_ = static_cast(LOAD_CONSTANT(kidx + 1)); - if (!InstanceCall(thread, target_name, call_base, call_top, &pc, &FP, - &SP)) { - HANDLE_EXCEPTION; - } - } - - DISPATCH(); - } - - { - BYTECODE(DynamicCall, D_F); - DEBUG_CHECK; - { - const uint32_t argc = rF; - const uint32_t kidx = rD; - - ObjectPtr* call_base = SP - argc + 1; - ObjectPtr* call_top = SP + 1; - - InterpreterHelpers::IncrementUsageCounter(FrameFunction(FP)); - StringPtr target_name = String::RawCast(LOAD_CONSTANT(kidx)); - argdesc_ = Array::RawCast(LOAD_CONSTANT(kidx + 1)); - if (!InstanceCall(thread, target_name, call_base, call_top, &pc, &FP, - &SP)) { - HANDLE_EXCEPTION; - } - } - - DISPATCH(); - } - - { - BYTECODE(NativeCall, D); - TypedDataPtr data = static_cast(LOAD_CONSTANT(rD)); - MethodRecognizer::Kind kind = NativeEntryData::GetKind(data); - switch (kind) { - case MethodRecognizer::kObjectEquals: { - SP[-1] = SP[-1] == SP[0] ? Bool::True().raw() : Bool::False().raw(); - SP--; - } break; - case MethodRecognizer::kStringBaseLength: - case MethodRecognizer::kStringBaseIsEmpty: { - InstancePtr instance = static_cast(SP[0]); - SP[0] = reinterpret_cast( - instance->ptr())[String::length_offset() / kWordSize]; - if (kind == MethodRecognizer::kStringBaseIsEmpty) { - SP[0] = - SP[0] == Smi::New(0) ? Bool::True().raw() : Bool::False().raw(); - } - } break; - case MethodRecognizer::kGrowableArrayLength: { - GrowableObjectArrayPtr instance = - static_cast(SP[0]); - SP[0] = instance->ptr()->length_; - } break; - case MethodRecognizer::kObjectArrayLength: - case MethodRecognizer::kImmutableArrayLength: { - ArrayPtr instance = static_cast(SP[0]); - SP[0] = instance->ptr()->length_; - } break; - case MethodRecognizer::kTypedListLength: - case MethodRecognizer::kTypedListViewLength: - case MethodRecognizer::kByteDataViewLength: { - TypedDataBasePtr instance = static_cast(SP[0]); - SP[0] = instance->ptr()->length_; - } break; - case MethodRecognizer::kByteDataViewOffsetInBytes: - case MethodRecognizer::kTypedDataViewOffsetInBytes: { - TypedDataViewPtr instance = static_cast(SP[0]); - SP[0] = instance->ptr()->offset_in_bytes_; - } break; - case MethodRecognizer::kByteDataViewTypedData: - case MethodRecognizer::kTypedDataViewTypedData: { - TypedDataViewPtr instance = static_cast(SP[0]); - SP[0] = instance->ptr()->typed_data_; - } break; - case MethodRecognizer::kClassIDgetID: { - SP[0] = InterpreterHelpers::GetClassIdAsSmi(SP[0]); - } break; - case MethodRecognizer::kAsyncStackTraceHelper: { - SP[0] = Object::null(); - } break; - case MethodRecognizer::kGrowableArrayCapacity: { - GrowableObjectArrayPtr instance = - static_cast(SP[0]); - SP[0] = instance->ptr()->data_->ptr()->length_; - } break; - case MethodRecognizer::kListFactory: { - // factory List([int length]) { - // return (:arg_desc.positional_count == 2) ? new _List(length) - // : new _GrowableList(0); - // } - if (InterpreterHelpers::ArgDescPosCount(argdesc_) == 2) { - TypeArgumentsPtr type_args = TypeArguments::RawCast(SP[-1]); - ObjectPtr length = SP[0]; - SP--; - if (!AllocateArray(thread, type_args, length, pc, FP, SP)) { - HANDLE_EXCEPTION; - } - } else { - ASSERT(InterpreterHelpers::ArgDescPosCount(argdesc_) == 1); - // SP[-1] is type. - // The native wrapper pushed null as the optional length argument. - ASSERT(SP[0] == null_value); - SP[0] = Smi::New(0); // Patch null length with zero length. - SP[1] = thread->isolate()->object_store()->growable_list_factory(); - // Change the ArgumentsDescriptor of the call with a new cached one. - argdesc_ = ArgumentsDescriptor::NewBoxed( - 0, KernelBytecode::kNativeCallToGrowableListArgc); - // Replace PC to the return trampoline so ReturnTOS would see - // a call bytecode at return address and will be able to get argc - // via DecodeArgc. - pc = KernelBytecode::GetNativeCallToGrowableListReturnTrampoline(); - if (!Invoke(thread, SP - 1, SP + 1, &pc, &FP, &SP)) { - HANDLE_EXCEPTION; - } - } - } break; - case MethodRecognizer::kObjectArrayAllocate: { - TypeArgumentsPtr type_args = TypeArguments::RawCast(SP[-1]); - ObjectPtr length = SP[0]; - SP--; - if (!AllocateArray(thread, type_args, length, pc, FP, SP)) { - HANDLE_EXCEPTION; - } - } break; - case MethodRecognizer::kLinkedHashMap_getIndex: { - InstancePtr instance = static_cast(SP[0]); - SP[0] = reinterpret_cast( - instance->ptr())[LinkedHashMap::index_offset() / kWordSize]; - } break; - case MethodRecognizer::kLinkedHashMap_setIndex: { - InstancePtr instance = static_cast(SP[-1]); - instance->ptr()->StorePointer( - reinterpret_cast(instance->ptr()) + - LinkedHashMap::index_offset() / kWordSize, - SP[0]); - *--SP = null_value; - } break; - case MethodRecognizer::kLinkedHashMap_getData: { - InstancePtr instance = static_cast(SP[0]); - SP[0] = reinterpret_cast( - instance->ptr())[LinkedHashMap::data_offset() / kWordSize]; - } break; - case MethodRecognizer::kLinkedHashMap_setData: { - InstancePtr instance = static_cast(SP[-1]); - instance->ptr()->StorePointer( - reinterpret_cast(instance->ptr()) + - LinkedHashMap::data_offset() / kWordSize, - SP[0]); - *--SP = null_value; - } break; - case MethodRecognizer::kLinkedHashMap_getHashMask: { - InstancePtr instance = static_cast(SP[0]); - SP[0] = reinterpret_cast( - instance->ptr())[LinkedHashMap::hash_mask_offset() / kWordSize]; - } break; - case MethodRecognizer::kLinkedHashMap_setHashMask: { - InstancePtr instance = static_cast(SP[-1]); - ASSERT(!SP[0]->IsHeapObject()); - reinterpret_cast( - instance->ptr())[LinkedHashMap::hash_mask_offset() / kWordSize] = - SP[0]; - *--SP = null_value; - } break; - case MethodRecognizer::kLinkedHashMap_getUsedData: { - InstancePtr instance = static_cast(SP[0]); - SP[0] = reinterpret_cast( - instance->ptr())[LinkedHashMap::used_data_offset() / kWordSize]; - } break; - case MethodRecognizer::kLinkedHashMap_setUsedData: { - InstancePtr instance = static_cast(SP[-1]); - ASSERT(!SP[0]->IsHeapObject()); - reinterpret_cast( - instance->ptr())[LinkedHashMap::used_data_offset() / kWordSize] = - SP[0]; - *--SP = null_value; - } break; - case MethodRecognizer::kLinkedHashMap_getDeletedKeys: { - InstancePtr instance = static_cast(SP[0]); - SP[0] = reinterpret_cast( - instance->ptr())[LinkedHashMap::deleted_keys_offset() / kWordSize]; - } break; - case MethodRecognizer::kLinkedHashMap_setDeletedKeys: { - InstancePtr instance = static_cast(SP[-1]); - ASSERT(!SP[0]->IsHeapObject()); - reinterpret_cast( - instance->ptr())[LinkedHashMap::deleted_keys_offset() / kWordSize] = - SP[0]; - *--SP = null_value; - } break; - case MethodRecognizer::kFfiAbi: { - *++SP = Smi::New(static_cast(compiler::ffi::TargetAbi())); - } break; -#define TYPED_DATA_FACTORY(clazz) \ - case MethodRecognizer::kTypedData_##clazz##_factory: { \ - ObjectPtr length = SP[0]; \ - SP[1] = Smi::New(kTypedData##clazz##Cid); \ - SP[2] = length; \ - Exit(thread, FP, SP + 3, pc); \ - INVOKE_RUNTIME(DRT_AllocateTypedData, \ - NativeArguments(thread, 2, SP + 1, SP)); \ - } break; - CLASS_LIST_TYPED_DATA(TYPED_DATA_FACTORY) -#undef TYPED_DATA_FACTORY - default: { - NativeEntryData::Payload* payload = - NativeEntryData::FromTypedArray(data); - intptr_t argc_tag = NativeEntryData::GetArgcTag(data); - const intptr_t num_arguments = - NativeArguments::ArgcBits::decode(argc_tag); - - if (payload->trampoline == NULL) { - ASSERT(payload->native_function == NULL); - payload->trampoline = &NativeEntry::BootstrapNativeCallWrapper; - payload->native_function = - reinterpret_cast(&NativeEntry::LinkNativeCall); - } - - *++SP = null_value; // Result slot. - - ObjectPtr* incoming_args = SP - num_arguments; - ObjectPtr* return_slot = SP; - Exit(thread, FP, SP + 1, pc); - NativeArguments native_args(thread, argc_tag, incoming_args, - return_slot); - INVOKE_NATIVE( - payload->trampoline, - reinterpret_cast(payload->native_function), - reinterpret_cast(&native_args)); - - *(SP - num_arguments) = *return_slot; - SP -= num_arguments; - } - } - DISPATCH(); - } - - { - BYTECODE(ReturnTOS, 0); - DEBUG_CHECK; - ObjectPtr result; // result to return to the caller. - result = *SP; - // Restore caller PC. - pc = SavedCallerPC(FP); - - // Check if it is a fake PC marking the entry frame. - if (IsEntryFrameMarker(pc)) { - // Pop entry frame. - ObjectPtr* entry_fp = SavedCallerFP(FP); - // Restore exit frame info saved in entry frame. - pp_ = static_cast(entry_fp[kKBCSavedPpSlotFromEntryFp]); - argdesc_ = - static_cast(entry_fp[kKBCSavedArgDescSlotFromEntryFp]); - uword exit_fp = static_cast(entry_fp[kKBCExitLinkSlotFromEntryFp]); - thread->set_top_exit_frame_info(exit_fp); - thread->set_top_resource(top_resource); - thread->set_vm_tag(vm_tag); - fp_ = entry_fp; - NOT_IN_PRODUCT(pc_ = pc); // For the profiler. -#if defined(DEBUG) - if (IsTracingExecution()) { - THR_Print("%" Pu64 " ", icount_); - THR_Print("Returning from interpreter 0x%" Px " at fp_ 0x%" Px - " exit 0x%" Px "\n", - reinterpret_cast(this), reinterpret_cast(fp_), - exit_fp); - } - ASSERT(HasFrame(reinterpret_cast(fp_))); - // Exception propagation should have been done. - ASSERT(!result->IsHeapObject() || - result->GetClassId() != kUnhandledExceptionCid); -#endif - return result; - } - - // Look at the caller to determine how many arguments to pop. - const uint8_t argc = KernelBytecode::DecodeArgc(pc); - - // Restore SP, FP and PP. Push result and dispatch. - SP = FrameArguments(FP, argc); - FP = SavedCallerFP(FP); - NOT_IN_PRODUCT(fp_ = FP); // For the profiler. - NOT_IN_PRODUCT(pc_ = pc); // For the profiler. - pp_ = InterpreterHelpers::FrameBytecode(FP)->ptr()->object_pool_; - *SP = result; -#if defined(DEBUG) - if (IsTracingExecution()) { - THR_Print("%" Pu64 " ", icount_); - THR_Print("Returning to %s (argc %d)\n", - Function::Handle(FrameFunction(FP)).ToFullyQualifiedCString(), - static_cast(argc)); - } -#endif - DISPATCH(); - } - - { - BYTECODE(InitLateField, D); - FieldPtr field = RAW_CAST(Field, LOAD_CONSTANT(rD + 1)); - InstancePtr instance = static_cast(SP[0]); - intptr_t offset_in_words = - Smi::Value(field->ptr()->host_offset_or_field_id_); - - instance->ptr()->StorePointer( - reinterpret_cast(instance->ptr()) + offset_in_words, - Object::RawCast(Object::sentinel().raw()), thread); - - SP -= 1; // Drop instance. - DISPATCH(); - } - - { - BYTECODE(PushUninitializedSentinel, 0); - *++SP = Object::sentinel().raw(); - DISPATCH(); - } - - { - BYTECODE(JumpIfInitialized, T); - SP -= 1; - if (SP[1] != Object::sentinel().raw()) { - LOAD_JUMP_TARGET(); - } - DISPATCH(); - } - - { - BYTECODE(StoreStaticTOS, D); - FieldPtr field = static_cast(LOAD_CONSTANT(rD)); - InstancePtr value = static_cast(*SP--); - intptr_t field_id = Smi::Value(field->ptr()->host_offset_or_field_id_); - thread->field_table_values()[field_id] = value; - DISPATCH(); - } - - { - BYTECODE(LoadStatic, D); - FieldPtr field = static_cast(LOAD_CONSTANT(rD)); - intptr_t field_id = Smi::Value(field->ptr()->host_offset_or_field_id_); - InstancePtr value = thread->field_table_values()[field_id]; - ASSERT((value != Object::sentinel().raw()) && - (value != Object::transition_sentinel().raw())); - *++SP = value; - DISPATCH(); - } - - { - BYTECODE(StoreFieldTOS, D); - FieldPtr field = RAW_CAST(Field, LOAD_CONSTANT(rD + 1)); - InstancePtr instance = static_cast(SP[-1]); - ObjectPtr value = static_cast(SP[0]); - intptr_t offset_in_words = - Smi::Value(field->ptr()->host_offset_or_field_id_); - - if (InterpreterHelpers::FieldNeedsGuardUpdate(field, value)) { - SP[1] = 0; // Unused result of runtime call. - SP[2] = field; - SP[3] = value; - Exit(thread, FP, SP + 4, pc); - if (!InvokeRuntime(thread, this, DRT_UpdateFieldCid, - NativeArguments(thread, 2, /* argv */ SP + 2, - /* retval */ SP + 1))) { - HANDLE_EXCEPTION; - } - - // Reload objects after the call which may trigger GC. - field = RAW_CAST(Field, LOAD_CONSTANT(rD + 1)); - instance = static_cast(SP[-1]); - value = SP[0]; - } - - const bool unboxing = - (field->ptr()->is_nullable_ != kNullCid) && - Field::UnboxingCandidateBit::decode(field->ptr()->kind_bits_); - classid_t guarded_cid = field->ptr()->guarded_cid_; - if (unboxing && (guarded_cid == kDoubleCid) && supports_unboxed_doubles_) { - double raw_value = Double::RawCast(value)->ptr()->value_; - ASSERT(*(reinterpret_cast(instance->ptr()) + - offset_in_words) == null_value); // Initializing store. - if (!AllocateDouble(thread, raw_value, pc, FP, SP)) { - HANDLE_EXCEPTION; - } - DoublePtr box = Double::RawCast(SP[0]); - instance = static_cast(SP[-1]); - instance->ptr()->StorePointer( - reinterpret_cast(instance->ptr()) + offset_in_words, box, - thread); - } else if (unboxing && (guarded_cid == kFloat32x4Cid) && - supports_unboxed_simd128_) { - simd128_value_t raw_value; - raw_value.readFrom(Float32x4::RawCast(value)->ptr()->value_); - ASSERT(*(reinterpret_cast(instance->ptr()) + - offset_in_words) == null_value); // Initializing store. - if (!AllocateFloat32x4(thread, raw_value, pc, FP, SP)) { - HANDLE_EXCEPTION; - } - Float32x4Ptr box = Float32x4::RawCast(SP[0]); - instance = static_cast(SP[-1]); - instance->ptr()->StorePointer( - reinterpret_cast(instance->ptr()) + offset_in_words, - box, thread); - } else if (unboxing && (guarded_cid == kFloat64x2Cid) && - supports_unboxed_simd128_) { - simd128_value_t raw_value; - raw_value.readFrom(Float64x2::RawCast(value)->ptr()->value_); - ASSERT(*(reinterpret_cast(instance->ptr()) + - offset_in_words) == null_value); // Initializing store. - if (!AllocateFloat64x2(thread, raw_value, pc, FP, SP)) { - HANDLE_EXCEPTION; - } - Float64x2Ptr box = Float64x2::RawCast(SP[0]); - instance = static_cast(SP[-1]); - instance->ptr()->StorePointer( - reinterpret_cast(instance->ptr()) + offset_in_words, - box, thread); - } else { - instance->ptr()->StorePointer( - reinterpret_cast(instance->ptr()) + offset_in_words, - value, thread); - } - - SP -= 2; // Drop instance and value. - DISPATCH(); - } - - { - BYTECODE(StoreContextParent, 0); - const uword offset_in_words = - static_cast(Context::parent_offset() / kWordSize); - ContextPtr instance = static_cast(SP[-1]); - ContextPtr value = static_cast(SP[0]); - SP -= 2; // Drop instance and value. - - instance->ptr()->StorePointer( - reinterpret_cast(instance->ptr()) + offset_in_words, value, - thread); - - DISPATCH(); - } - - { - BYTECODE(StoreContextVar, A_E); - const uword offset_in_words = - static_cast(Context::variable_offset(rE) / kWordSize); - ContextPtr instance = static_cast(SP[-1]); - ObjectPtr value = static_cast(SP[0]); - SP -= 2; // Drop instance and value. - ASSERT(rE < static_cast(instance->ptr()->num_variables_)); - instance->ptr()->StorePointer( - reinterpret_cast(instance->ptr()) + offset_in_words, value, - thread); - - DISPATCH(); - } - - { - BYTECODE(LoadFieldTOS, D); -#if defined(DEBUG) - // Currently only used to load closure fields, which are not unboxed. - // If used for general field, code for copying the mutable box must be - // added. - FieldPtr field = RAW_CAST(Field, LOAD_CONSTANT(rD + 1)); - const bool unboxing = - (field->ptr()->is_nullable_ != kNullCid) && - Field::UnboxingCandidateBit::decode(field->ptr()->kind_bits_); - ASSERT(!unboxing); -#endif - const uword offset_in_words = - static_cast(Smi::Value(RAW_CAST(Smi, LOAD_CONSTANT(rD)))); - InstancePtr instance = static_cast(SP[0]); - SP[0] = reinterpret_cast(instance->ptr())[offset_in_words]; - DISPATCH(); - } - - { - BYTECODE(LoadTypeArgumentsField, D); - const uword offset_in_words = - static_cast(Smi::Value(RAW_CAST(Smi, LOAD_CONSTANT(rD)))); - InstancePtr instance = static_cast(SP[0]); - SP[0] = reinterpret_cast(instance->ptr())[offset_in_words]; - DISPATCH(); - } - - { - BYTECODE(LoadContextParent, 0); - const uword offset_in_words = - static_cast(Context::parent_offset() / kWordSize); - ContextPtr instance = static_cast(SP[0]); - SP[0] = reinterpret_cast(instance->ptr())[offset_in_words]; - DISPATCH(); - } - - { - BYTECODE(LoadContextVar, A_E); - const uword offset_in_words = - static_cast(Context::variable_offset(rE) / kWordSize); - ContextPtr instance = static_cast(SP[0]); - ASSERT(rE < static_cast(instance->ptr()->num_variables_)); - SP[0] = reinterpret_cast(instance->ptr())[offset_in_words]; - DISPATCH(); - } - - { - BYTECODE(AllocateContext, A_E); - ++SP; - const uint32_t num_context_variables = rE; - if (!AllocateContext(thread, num_context_variables, pc, FP, SP)) { - HANDLE_EXCEPTION; - } - DISPATCH(); - } - - { - BYTECODE(CloneContext, A_E); - { - SP[1] = SP[0]; // Context to clone. - Exit(thread, FP, SP + 2, pc); - INVOKE_RUNTIME(DRT_CloneContext, NativeArguments(thread, 1, SP + 1, SP)); - } - DISPATCH(); - } - - { - BYTECODE(Allocate, D); - ClassPtr cls = Class::RawCast(LOAD_CONSTANT(rD)); - if (LIKELY(InterpreterHelpers::IsAllocateFinalized(cls))) { - const intptr_t class_id = cls->ptr()->id_; - const intptr_t instance_size = cls->ptr()->host_instance_size_in_words_ - << kWordSizeLog2; - ObjectPtr result; - if (TryAllocate(thread, class_id, instance_size, &result)) { - uword start = ObjectLayout::ToAddr(result); - for (intptr_t offset = sizeof(InstanceLayout); offset < instance_size; - offset += kWordSize) { - *reinterpret_cast(start + offset) = null_value; - } - *++SP = result; - DISPATCH(); - } - } - - SP[1] = 0; // Space for the result. - SP[2] = cls; // Class object. - SP[3] = null_value; // Type arguments. - Exit(thread, FP, SP + 4, pc); - INVOKE_RUNTIME(DRT_AllocateObject, - NativeArguments(thread, 2, SP + 2, SP + 1)); - SP++; // Result is in SP[1]. - DISPATCH(); - } - - { - BYTECODE(AllocateT, 0); - ClassPtr cls = Class::RawCast(SP[0]); - TypeArgumentsPtr type_args = TypeArguments::RawCast(SP[-1]); - if (LIKELY(InterpreterHelpers::IsAllocateFinalized(cls))) { - const intptr_t class_id = cls->ptr()->id_; - const intptr_t instance_size = cls->ptr()->host_instance_size_in_words_ - << kWordSizeLog2; - ObjectPtr result; - if (TryAllocate(thread, class_id, instance_size, &result)) { - uword start = ObjectLayout::ToAddr(result); - for (intptr_t offset = sizeof(InstanceLayout); offset < instance_size; - offset += kWordSize) { - *reinterpret_cast(start + offset) = null_value; - } - const intptr_t type_args_offset = - cls->ptr()->host_type_arguments_field_offset_in_words_ - << kWordSizeLog2; - *reinterpret_cast(start + type_args_offset) = type_args; - *--SP = result; - DISPATCH(); - } - } - - SP[1] = cls; - SP[2] = type_args; - Exit(thread, FP, SP + 3, pc); - INVOKE_RUNTIME(DRT_AllocateObject, - NativeArguments(thread, 2, SP + 1, SP - 1)); - SP -= 1; // Result is in SP - 1. - DISPATCH(); - } - - { - BYTECODE(CreateArrayTOS, 0); - TypeArgumentsPtr type_args = TypeArguments::RawCast(SP[-1]); - ObjectPtr length = SP[0]; - SP--; - if (!AllocateArray(thread, type_args, length, pc, FP, SP)) { - HANDLE_EXCEPTION; - } - DISPATCH(); - } - - { - BYTECODE(AssertAssignable, A_E); - // Stack: instance, type, instantiator type args, function type args, name - ObjectPtr* args = SP - 4; - const bool may_be_smi = (rA == 1); - const bool is_smi = - ((static_cast(args[0]) & kSmiTagMask) == kSmiTag); - const bool smi_ok = is_smi && may_be_smi; - if (!smi_ok && (args[0] != null_value)) { - SubtypeTestCachePtr cache = - static_cast(LOAD_CONSTANT(rE)); - - if (!AssertAssignable(thread, pc, FP, SP, args, cache)) { - HANDLE_EXCEPTION; - } - } - - SP -= 4; // Instance remains on stack. - DISPATCH(); - } - - { - BYTECODE(AssertSubtype, 0); - ObjectPtr* args = SP - 4; - - // TODO(kustermann): Implement fast case for common arguments. - - // The arguments on the stack look like: - // args[0] instantiator type args - // args[1] function type args - // args[2] sub_type - // args[3] super_type - // args[4] name - - // This is unused, since the negative case throws an exception. - SP++; - ObjectPtr* result_slot = SP; - - Exit(thread, FP, SP + 1, pc); - INVOKE_RUNTIME(DRT_SubtypeCheck, - NativeArguments(thread, 5, args, result_slot)); - - // Drop result slot and all arguments. - SP -= 6; - - DISPATCH(); - } - - { - BYTECODE(AssertBoolean, A); - ObjectPtr value = SP[0]; - if (rA != 0u) { // Should we perform type check? - if ((value == true_value) || (value == false_value)) { - goto AssertBooleanOk; - } - } else if (value != null_value) { - goto AssertBooleanOk; - } - - // Assertion failed. - { - SP[1] = SP[0]; // instance - Exit(thread, FP, SP + 2, pc); - INVOKE_RUNTIME(DRT_NonBoolTypeError, - NativeArguments(thread, 1, SP + 1, SP)); - } - - AssertBooleanOk: - DISPATCH(); - } - - { - BYTECODE(Jump, T); - LOAD_JUMP_TARGET(); - DISPATCH(); - } - - { - BYTECODE(JumpIfNoAsserts, T); - if (!thread->isolate()->asserts()) { - LOAD_JUMP_TARGET(); - } - DISPATCH(); - } - - { - BYTECODE(JumpIfNotZeroTypeArgs, T); - if (InterpreterHelpers::ArgDescTypeArgsLen(argdesc_) != 0) { - LOAD_JUMP_TARGET(); - } - DISPATCH(); - } - - { - BYTECODE(JumpIfEqStrict, T); - SP -= 2; - if (SP[1] == SP[2]) { - LOAD_JUMP_TARGET(); - } - DISPATCH(); - } - - { - BYTECODE(JumpIfNeStrict, T); - SP -= 2; - if (SP[1] != SP[2]) { - LOAD_JUMP_TARGET(); - } - DISPATCH(); - } - - { - BYTECODE(JumpIfTrue, T); - SP -= 1; - if (SP[1] == true_value) { - LOAD_JUMP_TARGET(); - } - DISPATCH(); - } - - { - BYTECODE(JumpIfFalse, T); - SP -= 1; - if (SP[1] == false_value) { - LOAD_JUMP_TARGET(); - } - DISPATCH(); - } - - { - BYTECODE(JumpIfNull, T); - SP -= 1; - if (SP[1] == null_value) { - LOAD_JUMP_TARGET(); - } - DISPATCH(); - } - - { - BYTECODE(JumpIfNotNull, T); - SP -= 1; - if (SP[1] != null_value) { - LOAD_JUMP_TARGET(); - } - DISPATCH(); - } - - { - BYTECODE(JumpIfUnchecked, T); - // Interpreter is not tracking unchecked calls, so fall through to - // parameter type checks. - DISPATCH(); - } - - { - BYTECODE(StoreIndexedTOS, 0); - SP -= 3; - ArrayPtr array = RAW_CAST(Array, SP[1]); - SmiPtr index = RAW_CAST(Smi, SP[2]); - ObjectPtr value = SP[3]; - ASSERT(InterpreterHelpers::CheckIndex(index, array->ptr()->length_)); - array->ptr()->StorePointer(array->ptr()->data() + Smi::Value(index), value, - thread); - DISPATCH(); - } - - { - BYTECODE(EqualsNull, 0); - DEBUG_CHECK; - SP[0] = (SP[0] == null_value) ? true_value : false_value; - DISPATCH(); - } - - { - BYTECODE(NullCheck, D); - - if (UNLIKELY(SP[0] == null_value)) { - // Load selector. - SP[0] = LOAD_CONSTANT(rD); - goto ThrowNullError; - } - SP -= 1; - - DISPATCH(); - } - - { - BYTECODE(NegateInt, 0); - DEBUG_CHECK; - UNBOX_INT64(value, SP[0], Symbols::UnaryMinus()); - int64_t result = Utils::SubWithWrapAround(0, value); - BOX_INT64_RESULT(result); - DISPATCH(); - } - - { - BYTECODE(AddInt, 0); - DEBUG_CHECK; - SP -= 1; - UNBOX_INT64(a, SP[0], Symbols::Plus()); - UNBOX_INT64(b, SP[1], Symbols::Plus()); - int64_t result = Utils::AddWithWrapAround(a, b); - BOX_INT64_RESULT(result); - DISPATCH(); - } - - { - BYTECODE(SubInt, 0); - DEBUG_CHECK; - SP -= 1; - UNBOX_INT64(a, SP[0], Symbols::Minus()); - UNBOX_INT64(b, SP[1], Symbols::Minus()); - int64_t result = Utils::SubWithWrapAround(a, b); - BOX_INT64_RESULT(result); - DISPATCH(); - } - - { - BYTECODE(MulInt, 0); - DEBUG_CHECK; - SP -= 1; - UNBOX_INT64(a, SP[0], Symbols::Star()); - UNBOX_INT64(b, SP[1], Symbols::Star()); - int64_t result = Utils::MulWithWrapAround(a, b); - BOX_INT64_RESULT(result); - DISPATCH(); - } - - { - BYTECODE(TruncDivInt, 0); - DEBUG_CHECK; - SP -= 1; - UNBOX_INT64(a, SP[0], Symbols::TruncDivOperator()); - UNBOX_INT64(b, SP[1], Symbols::TruncDivOperator()); - if (UNLIKELY(b == 0)) { - goto ThrowIntegerDivisionByZeroException; - } - int64_t result; - if (UNLIKELY((a == Mint::kMinValue) && (b == -1))) { - result = Mint::kMinValue; - } else { - result = a / b; - } - BOX_INT64_RESULT(result); - DISPATCH(); - } - - { - BYTECODE(ModInt, 0); - DEBUG_CHECK; - SP -= 1; - UNBOX_INT64(a, SP[0], Symbols::Percent()); - UNBOX_INT64(b, SP[1], Symbols::Percent()); - if (UNLIKELY(b == 0)) { - goto ThrowIntegerDivisionByZeroException; - } - int64_t result; - if (UNLIKELY((a == Mint::kMinValue) && (b == -1))) { - result = 0; - } else { - result = a % b; - if (result < 0) { - if (b < 0) { - result -= b; - } else { - result += b; - } - } - } - BOX_INT64_RESULT(result); - DISPATCH(); - } - - { - BYTECODE(BitAndInt, 0); - DEBUG_CHECK; - SP -= 1; - UNBOX_INT64(a, SP[0], Symbols::Ampersand()); - UNBOX_INT64(b, SP[1], Symbols::Ampersand()); - int64_t result = a & b; - BOX_INT64_RESULT(result); - DISPATCH(); - } - - { - BYTECODE(BitOrInt, 0); - DEBUG_CHECK; - SP -= 1; - UNBOX_INT64(a, SP[0], Symbols::BitOr()); - UNBOX_INT64(b, SP[1], Symbols::BitOr()); - int64_t result = a | b; - BOX_INT64_RESULT(result); - DISPATCH(); - } - - { - BYTECODE(BitXorInt, 0); - DEBUG_CHECK; - SP -= 1; - UNBOX_INT64(a, SP[0], Symbols::Caret()); - UNBOX_INT64(b, SP[1], Symbols::Caret()); - int64_t result = a ^ b; - BOX_INT64_RESULT(result); - DISPATCH(); - } - - { - BYTECODE(ShlInt, 0); - DEBUG_CHECK; - SP -= 1; - UNBOX_INT64(a, SP[0], Symbols::LeftShiftOperator()); - UNBOX_INT64(b, SP[1], Symbols::LeftShiftOperator()); - if (b < 0) { - SP[0] = SP[1]; - goto ThrowArgumentError; - } - int64_t result = Utils::ShiftLeftWithTruncation(a, b); - BOX_INT64_RESULT(result); - DISPATCH(); - } - - { - BYTECODE(ShrInt, 0); - DEBUG_CHECK; - SP -= 1; - UNBOX_INT64(a, SP[0], Symbols::RightShiftOperator()); - UNBOX_INT64(b, SP[1], Symbols::RightShiftOperator()); - if (b < 0) { - SP[0] = SP[1]; - goto ThrowArgumentError; - } - int64_t result = a >> Utils::Minimum(b, Mint::kBits); - BOX_INT64_RESULT(result); - DISPATCH(); - } - - { - BYTECODE(CompareIntEq, 0); - DEBUG_CHECK; - SP -= 1; - if (SP[0] == SP[1]) { - SP[0] = true_value; - } else if (!SP[0]->IsHeapObject() || !SP[1]->IsHeapObject() || - (SP[0] == null_value) || (SP[1] == null_value)) { - SP[0] = false_value; - } else { - int64_t a = Integer::GetInt64Value(RAW_CAST(Integer, SP[0])); - int64_t b = Integer::GetInt64Value(RAW_CAST(Integer, SP[1])); - SP[0] = (a == b) ? true_value : false_value; - } - DISPATCH(); - } - - { - BYTECODE(CompareIntGt, 0); - DEBUG_CHECK; - SP -= 1; - UNBOX_INT64(a, SP[0], Symbols::RAngleBracket()); - UNBOX_INT64(b, SP[1], Symbols::RAngleBracket()); - SP[0] = (a > b) ? true_value : false_value; - DISPATCH(); - } - - { - BYTECODE(CompareIntLt, 0); - DEBUG_CHECK; - SP -= 1; - UNBOX_INT64(a, SP[0], Symbols::LAngleBracket()); - UNBOX_INT64(b, SP[1], Symbols::LAngleBracket()); - SP[0] = (a < b) ? true_value : false_value; - DISPATCH(); - } - - { - BYTECODE(CompareIntGe, 0); - DEBUG_CHECK; - SP -= 1; - UNBOX_INT64(a, SP[0], Symbols::GreaterEqualOperator()); - UNBOX_INT64(b, SP[1], Symbols::GreaterEqualOperator()); - SP[0] = (a >= b) ? true_value : false_value; - DISPATCH(); - } - - { - BYTECODE(CompareIntLe, 0); - DEBUG_CHECK; - SP -= 1; - UNBOX_INT64(a, SP[0], Symbols::LessEqualOperator()); - UNBOX_INT64(b, SP[1], Symbols::LessEqualOperator()); - SP[0] = (a <= b) ? true_value : false_value; - DISPATCH(); - } - - { - BYTECODE(NegateDouble, 0); - DEBUG_CHECK; - UNBOX_DOUBLE(value, SP[0], Symbols::UnaryMinus()); - double result = -value; - BOX_DOUBLE_RESULT(result); - DISPATCH(); - } - - { - BYTECODE(AddDouble, 0); - DEBUG_CHECK; - SP -= 1; - UNBOX_DOUBLE(a, SP[0], Symbols::Plus()); - UNBOX_DOUBLE(b, SP[1], Symbols::Plus()); - double result = a + b; - BOX_DOUBLE_RESULT(result); - DISPATCH(); - } - - { - BYTECODE(SubDouble, 0); - DEBUG_CHECK; - SP -= 1; - UNBOX_DOUBLE(a, SP[0], Symbols::Minus()); - UNBOX_DOUBLE(b, SP[1], Symbols::Minus()); - double result = a - b; - BOX_DOUBLE_RESULT(result); - DISPATCH(); - } - - { - BYTECODE(MulDouble, 0); - DEBUG_CHECK; - SP -= 1; - UNBOX_DOUBLE(a, SP[0], Symbols::Star()); - UNBOX_DOUBLE(b, SP[1], Symbols::Star()); - double result = a * b; - BOX_DOUBLE_RESULT(result); - DISPATCH(); - } - - { - BYTECODE(DivDouble, 0); - DEBUG_CHECK; - SP -= 1; - UNBOX_DOUBLE(a, SP[0], Symbols::Slash()); - UNBOX_DOUBLE(b, SP[1], Symbols::Slash()); - double result = a / b; - BOX_DOUBLE_RESULT(result); - DISPATCH(); - } - - { - BYTECODE(CompareDoubleEq, 0); - DEBUG_CHECK; - SP -= 1; - if ((SP[0] == null_value) || (SP[1] == null_value)) { - SP[0] = (SP[0] == SP[1]) ? true_value : false_value; - } else { - double a = Double::RawCast(SP[0])->ptr()->value_; - double b = Double::RawCast(SP[1])->ptr()->value_; - SP[0] = (a == b) ? true_value : false_value; - } - DISPATCH(); - } - - { - BYTECODE(CompareDoubleGt, 0); - DEBUG_CHECK; - SP -= 1; - UNBOX_DOUBLE(a, SP[0], Symbols::RAngleBracket()); - UNBOX_DOUBLE(b, SP[1], Symbols::RAngleBracket()); - SP[0] = (a > b) ? true_value : false_value; - DISPATCH(); - } - - { - BYTECODE(CompareDoubleLt, 0); - DEBUG_CHECK; - SP -= 1; - UNBOX_DOUBLE(a, SP[0], Symbols::LAngleBracket()); - UNBOX_DOUBLE(b, SP[1], Symbols::LAngleBracket()); - SP[0] = (a < b) ? true_value : false_value; - DISPATCH(); - } - - { - BYTECODE(CompareDoubleGe, 0); - DEBUG_CHECK; - SP -= 1; - UNBOX_DOUBLE(a, SP[0], Symbols::GreaterEqualOperator()); - UNBOX_DOUBLE(b, SP[1], Symbols::GreaterEqualOperator()); - SP[0] = (a >= b) ? true_value : false_value; - DISPATCH(); - } - - { - BYTECODE(CompareDoubleLe, 0); - DEBUG_CHECK; - SP -= 1; - UNBOX_DOUBLE(a, SP[0], Symbols::LessEqualOperator()); - UNBOX_DOUBLE(b, SP[1], Symbols::LessEqualOperator()); - SP[0] = (a <= b) ? true_value : false_value; - DISPATCH(); - } - - { - BYTECODE(AllocateClosure, D); - ++SP; - if (!AllocateClosure(thread, pc, FP, SP)) { - HANDLE_EXCEPTION; - } - DISPATCH(); - } - - { - BYTECODE_ENTRY_LABEL(Trap); - -#define UNIMPLEMENTED_LABEL_ORDN(Name) -#define UNIMPLEMENTED_LABEL_WIDE(Name) -#define UNIMPLEMENTED_LABEL_RESV(Name) BYTECODE_ENTRY_LABEL(Name) -#define UNIMPLEMENTED_LABEL(name, encoding, kind, op1, op2, op3) \ - UNIMPLEMENTED_LABEL_##kind(name) - - KERNEL_BYTECODES_LIST(UNIMPLEMENTED_LABEL) - -#undef UNIMPLEMENTED_LABEL_ORDN -#undef UNIMPLEMENTED_LABEL_WIDE -#undef UNIMPLEMENTED_LABEL_RESV -#undef UNIMPLEMENTED_LABEL - - UNIMPLEMENTED(); - DISPATCH(); - } - - { - BYTECODE(VMInternal_ImplicitGetter, 0); - - FunctionPtr function = FrameFunction(FP); - ASSERT(Function::kind(function) == FunctionLayout::kImplicitGetter); - - BUMP_USAGE_COUNTER_ON_ENTRY(function); - - // Field object is cached in function's data_. - FieldPtr field = static_cast(function->ptr()->data_); - intptr_t offset_in_words = - Smi::Value(field->ptr()->host_offset_or_field_id_); - - const intptr_t kArgc = 1; - InstancePtr instance = - static_cast(FrameArguments(FP, kArgc)[0]); - InstancePtr value = - reinterpret_cast(instance->ptr())[offset_in_words]; - - if (UNLIKELY(value == Object::sentinel().raw())) { - SP[1] = 0; // Result slot. - SP[2] = instance; - SP[3] = field; - Exit(thread, FP, SP + 4, pc); - INVOKE_RUNTIME( - DRT_InitInstanceField, - NativeArguments(thread, 2, /* argv */ SP + 2, /* ret val */ SP + 1)); - - function = FrameFunction(FP); - instance = static_cast(SP[2]); - field = static_cast(SP[3]); - offset_in_words = Smi::Value(field->ptr()->host_offset_or_field_id_); - value = reinterpret_cast(instance->ptr())[offset_in_words]; - } - - *++SP = value; - -#if !defined(PRODUCT) - if (UNLIKELY(Field::NeedsLoadGuardBit::decode(field->ptr()->kind_bits_))) { - if (!AssertAssignableField(thread, pc, FP, SP, instance, field, - value)) { - HANDLE_EXCEPTION; - } - // Reload objects after the call which may trigger GC. - field = static_cast(FrameFunction(FP)->ptr()->data_); - instance = static_cast(FrameArguments(FP, kArgc)[0]); - value = reinterpret_cast(instance->ptr())[offset_in_words]; - } -#endif - - const bool unboxing = - (field->ptr()->is_nullable_ != kNullCid) && - Field::UnboxingCandidateBit::decode(field->ptr()->kind_bits_); - classid_t guarded_cid = field->ptr()->guarded_cid_; - if (unboxing && (guarded_cid == kDoubleCid) && supports_unboxed_doubles_) { - ASSERT(FlowGraphCompiler::SupportsUnboxedDoubles()); - double raw_value = Double::RawCast(value)->ptr()->value_; - // AllocateDouble places result at SP[0] - if (!AllocateDouble(thread, raw_value, pc, FP, SP)) { - HANDLE_EXCEPTION; - } - } else if (unboxing && (guarded_cid == kFloat32x4Cid) && - supports_unboxed_simd128_) { - simd128_value_t raw_value; - raw_value.readFrom(Float32x4::RawCast(value)->ptr()->value_); - // AllocateFloat32x4 places result at SP[0] - if (!AllocateFloat32x4(thread, raw_value, pc, FP, SP)) { - HANDLE_EXCEPTION; - } - } else if (unboxing && (guarded_cid == kFloat64x2Cid) && - supports_unboxed_simd128_) { - simd128_value_t raw_value; - raw_value.readFrom(Float64x2::RawCast(value)->ptr()->value_); - // AllocateFloat64x2 places result at SP[0] - if (!AllocateFloat64x2(thread, raw_value, pc, FP, SP)) { - HANDLE_EXCEPTION; - } - } - - DISPATCH(); - } - - { - BYTECODE(VMInternal_ImplicitSetter, 0); - - FunctionPtr function = FrameFunction(FP); - ASSERT(Function::kind(function) == FunctionLayout::kImplicitSetter); - - BUMP_USAGE_COUNTER_ON_ENTRY(function); - - // Field object is cached in function's data_. - FieldPtr field = static_cast(function->ptr()->data_); - intptr_t offset_in_words = - Smi::Value(field->ptr()->host_offset_or_field_id_); - const intptr_t kArgc = 2; - InstancePtr instance = - static_cast(FrameArguments(FP, kArgc)[0]); - InstancePtr value = static_cast(FrameArguments(FP, kArgc)[1]); - - if (!AssertAssignableField(thread, pc, FP, SP, instance, field, - value)) { - HANDLE_EXCEPTION; - } - // Reload objects after the call which may trigger GC. - field = static_cast(FrameFunction(FP)->ptr()->data_); - instance = static_cast(FrameArguments(FP, kArgc)[0]); - value = static_cast(FrameArguments(FP, kArgc)[1]); - - if (InterpreterHelpers::FieldNeedsGuardUpdate(field, value)) { - SP[1] = 0; // Unused result of runtime call. - SP[2] = field; - SP[3] = value; - Exit(thread, FP, SP + 4, pc); - if (!InvokeRuntime(thread, this, DRT_UpdateFieldCid, - NativeArguments(thread, 2, /* argv */ SP + 2, - /* retval */ SP + 1))) { - HANDLE_EXCEPTION; - } - - // Reload objects after the call which may trigger GC. - field = static_cast(FrameFunction(FP)->ptr()->data_); - instance = static_cast(FrameArguments(FP, kArgc)[0]); - value = static_cast(FrameArguments(FP, kArgc)[1]); - } - - const bool unboxing = - (field->ptr()->is_nullable_ != kNullCid) && - Field::UnboxingCandidateBit::decode(field->ptr()->kind_bits_); - classid_t guarded_cid = field->ptr()->guarded_cid_; - if (unboxing && (guarded_cid == kDoubleCid) && supports_unboxed_doubles_) { - double raw_value = Double::RawCast(value)->ptr()->value_; - DoublePtr box = - *(reinterpret_cast(instance->ptr()) + offset_in_words); - ASSERT(box != null_value); // Non-initializing store. - box->ptr()->value_ = raw_value; - } else if (unboxing && (guarded_cid == kFloat32x4Cid) && - supports_unboxed_simd128_) { - simd128_value_t raw_value; - raw_value.readFrom(Float32x4::RawCast(value)->ptr()->value_); - Float32x4Ptr box = - *(reinterpret_cast(instance->ptr()) + offset_in_words); - ASSERT(box != null_value); // Non-initializing store. - raw_value.writeTo(box->ptr()->value_); - } else if (unboxing && (guarded_cid == kFloat64x2Cid) && - supports_unboxed_simd128_) { - simd128_value_t raw_value; - raw_value.readFrom(Float64x2::RawCast(value)->ptr()->value_); - Float64x2Ptr box = - *(reinterpret_cast(instance->ptr()) + offset_in_words); - ASSERT(box != null_value); // Non-initializing store. - raw_value.writeTo(box->ptr()->value_); - } else { - instance->ptr()->StorePointer( - reinterpret_cast(instance->ptr()) + offset_in_words, - value, thread); - } - - *++SP = null_value; - - DISPATCH(); - } - - { - BYTECODE(VMInternal_ImplicitStaticGetter, 0); - - FunctionPtr function = FrameFunction(FP); - ASSERT(Function::kind(function) == FunctionLayout::kImplicitStaticGetter); - - BUMP_USAGE_COUNTER_ON_ENTRY(function); - - // Field object is cached in function's data_. - FieldPtr field = static_cast(function->ptr()->data_); - intptr_t field_id = Smi::Value(field->ptr()->host_offset_or_field_id_); - InstancePtr value = thread->field_table_values()[field_id]; - if (value == Object::sentinel().raw() || - value == Object::transition_sentinel().raw()) { - SP[1] = 0; // Unused result of invoking the initializer. - SP[2] = field; - Exit(thread, FP, SP + 3, pc); - INVOKE_RUNTIME(DRT_InitStaticField, - NativeArguments(thread, 1, SP + 2, SP + 1)); - - // Reload objects after the call which may trigger GC. - function = FrameFunction(FP); - field = static_cast(function->ptr()->data_); - // The field is initialized by the runtime call, but not returned. - intptr_t field_id = Smi::Value(field->ptr()->host_offset_or_field_id_); - value = thread->field_table_values()[field_id]; - } - - // Field was initialized. Return its value. - *++SP = value; - -#if !defined(PRODUCT) - if (UNLIKELY(Field::NeedsLoadGuardBit::decode(field->ptr()->kind_bits_))) { - if (!AssertAssignableField(thread, pc, FP, SP, - static_cast(null_value), - field, value)) { - HANDLE_EXCEPTION; - } - } -#endif - - DISPATCH(); - } - - { - BYTECODE(VMInternal_MethodExtractor, 0); - - FunctionPtr function = FrameFunction(FP); - ASSERT(Function::kind(function) == FunctionLayout::kMethodExtractor); - - BUMP_USAGE_COUNTER_ON_ENTRY(function); - - ASSERT(InterpreterHelpers::ArgDescTypeArgsLen(argdesc_) == 0); - - ++SP; - if (!AllocateClosure(thread, pc, FP, SP)) { - HANDLE_EXCEPTION; - } - - ++SP; - if (!AllocateContext(thread, 1, pc, FP, SP)) { - HANDLE_EXCEPTION; - } - - ContextPtr context = Context::RawCast(*SP--); - InstancePtr instance = Instance::RawCast(FrameArguments(FP, 1)[0]); - context->ptr()->StorePointer( - reinterpret_cast(&context->ptr()->data()[0]), instance); - - ClosurePtr closure = Closure::RawCast(*SP); - closure->ptr()->StorePointer( - &closure->ptr()->instantiator_type_arguments_, - InterpreterHelpers::GetTypeArguments(thread, instance)); - // function_type_arguments_ is already null - closure->ptr()->delayed_type_arguments_ = - Object::empty_type_arguments().raw(); - closure->ptr()->StorePointer( - &closure->ptr()->function_, - Function::RawCast(FrameFunction(FP)->ptr()->data_)); - closure->ptr()->StorePointer(&closure->ptr()->context_, context); - // hash_ is already null - - DISPATCH(); - } - - { - BYTECODE(VMInternal_InvokeClosure, 0); - - FunctionPtr function = FrameFunction(FP); - ASSERT(Function::kind(function) == FunctionLayout::kInvokeFieldDispatcher); - const bool is_dynamic_call = - Function::IsDynamicInvocationForwarderName(function->ptr()->name_); - - BUMP_USAGE_COUNTER_ON_ENTRY(function); - - const intptr_t type_args_len = - InterpreterHelpers::ArgDescTypeArgsLen(argdesc_); - const intptr_t receiver_idx = type_args_len > 0 ? 1 : 0; - const intptr_t argc = - InterpreterHelpers::ArgDescArgCount(argdesc_) + receiver_idx; - - ClosurePtr receiver = - Closure::RawCast(FrameArguments(FP, argc)[receiver_idx]); - SP[1] = receiver->ptr()->function_; - - if (is_dynamic_call) { - { - SP[2] = null_value; - SP[3] = receiver; - SP[4] = argdesc_; - Exit(thread, FP, SP + 5, pc); - if (!InvokeRuntime(thread, this, DRT_ClosureArgumentsValid, - NativeArguments(thread, 2, SP + 3, SP + 2))) { - HANDLE_EXCEPTION; - } - receiver = Closure::RawCast(SP[3]); - argdesc_ = Array::RawCast(SP[4]); - } - - if (SP[2] != Bool::True().raw()) { - goto NoSuchMethodFromPrologue; - } - - // TODO(dartbug.com/40813): Move other checks that are currently - // compiled in the closure body to here as they are also moved to - // FlowGraphBuilder::BuildGraphOfInvokeFieldDispatcher. - } - - goto TailCallSP1; - } - - { - BYTECODE(VMInternal_InvokeField, 0); - - FunctionPtr function = FrameFunction(FP); - ASSERT(Function::kind(function) == FunctionLayout::kInvokeFieldDispatcher); - - BUMP_USAGE_COUNTER_ON_ENTRY(function); - - const intptr_t type_args_len = - InterpreterHelpers::ArgDescTypeArgsLen(argdesc_); - const intptr_t receiver_idx = type_args_len > 0 ? 1 : 0; - const intptr_t argc = - InterpreterHelpers::ArgDescArgCount(argdesc_) + receiver_idx; - ObjectPtr receiver = FrameArguments(FP, argc)[receiver_idx]; - - // Possibly demangle field name and invoke field getter on receiver. - { - SP[1] = argdesc_; // Save argdesc_. - SP[2] = 0; // Result of runtime call. - SP[3] = receiver; // Receiver. - SP[4] = function->ptr()->name_; // Field name (may change during call). - Exit(thread, FP, SP + 5, pc); - if (!InvokeRuntime(thread, this, DRT_GetFieldForDispatch, - NativeArguments(thread, 2, SP + 3, SP + 2))) { - HANDLE_EXCEPTION; - } - function = FrameFunction(FP); - argdesc_ = Array::RawCast(SP[1]); - } - - // If the field name in the arguments is different after the call, then - // this was a dynamic call. - StringPtr field_name = String::RawCast(SP[4]); - const bool is_dynamic_call = function->ptr()->name_ != field_name; - - // Replace receiver with field value, keep all other arguments, and - // invoke 'call' function, or if not found, invoke noSuchMethod. - FrameArguments(FP, argc)[receiver_idx] = receiver = SP[2]; - - // If the field value is a closure, no need to resolve 'call' function. - if (InterpreterHelpers::GetClassId(receiver) == kClosureCid) { - SP[1] = Closure::RawCast(receiver)->ptr()->function_; - - if (is_dynamic_call) { - { - SP[2] = null_value; - SP[3] = receiver; - SP[4] = argdesc_; - Exit(thread, FP, SP + 5, pc); - if (!InvokeRuntime(thread, this, DRT_ClosureArgumentsValid, - NativeArguments(thread, 2, SP + 3, SP + 2))) { - HANDLE_EXCEPTION; - } - receiver = SP[3]; - argdesc_ = Array::RawCast(SP[4]); - } - - if (SP[2] != Bool::True().raw()) { - goto NoSuchMethodFromPrologue; - } - - // TODO(dartbug.com/40813): Move other checks that are currently - // compiled in the closure body to here as they are also moved to - // FlowGraphBuilder::BuildGraphOfInvokeFieldDispatcher. - } - - goto TailCallSP1; - } - - // Otherwise, call runtime to resolve 'call' function. - { - SP[1] = 0; // Result slot. - SP[2] = receiver; - SP[3] = argdesc_; - Exit(thread, FP, SP + 4, pc); - if (!InvokeRuntime(thread, this, DRT_ResolveCallFunction, - NativeArguments(thread, 2, SP + 2, SP + 1))) { - HANDLE_EXCEPTION; - } - argdesc_ = Array::RawCast(SP[3]); - function = Function::RawCast(SP[1]); - receiver = SP[2]; - } - - if (function != Function::null()) { - SP[1] = function; - goto TailCallSP1; - } - - // Function 'call' could not be resolved for argdesc_. - // Invoke noSuchMethod. - SP[1] = null_value; - SP[2] = receiver; - SP[3] = Symbols::Call().raw(); // We failed to resolve the 'call' function. - SP[4] = argdesc_; - SP[5] = null_value; // Array of arguments (will be filled). - - // Allocate array of arguments. - { - SP[6] = Smi::New(argc); // length - SP[7] = null_value; // type - Exit(thread, FP, SP + 8, pc); - if (!InvokeRuntime(thread, this, DRT_AllocateArray, - NativeArguments(thread, 2, SP + 6, SP + 5))) { - HANDLE_EXCEPTION; - } - } - - // Copy arguments into the newly allocated array. - ObjectPtr* argv = FrameArguments(FP, argc); - ArrayPtr array = static_cast(SP[5]); - ASSERT(array->GetClassId() == kArrayCid); - for (intptr_t i = 0; i < argc; i++) { - array->ptr()->data()[i] = argv[i]; - } - - // Invoke noSuchMethod passing down receiver, target name, argument - // descriptor, and array of arguments. - { - Exit(thread, FP, SP + 6, pc); - if (!InvokeRuntime(thread, this, DRT_InvokeNoSuchMethod, - NativeArguments(thread, 4, SP + 2, SP + 1))) { - HANDLE_EXCEPTION; - } - - ++SP; // Result at SP[0] - } - DISPATCH(); - } - - { - BYTECODE(VMInternal_ForwardDynamicInvocation, 0); - FunctionPtr function = FrameFunction(FP); - ASSERT(Function::kind(function) == - FunctionLayout::kDynamicInvocationForwarder); - - BUMP_USAGE_COUNTER_ON_ENTRY(function); - - ArrayPtr checks = Array::RawCast(function->ptr()->data_); - FunctionPtr target = Function::RawCast(checks->ptr()->data()[0]); - ASSERT(Function::kind(target) != - FunctionLayout::kDynamicInvocationForwarder); - BytecodePtr target_bytecode = target->ptr()->bytecode_; - ASSERT(target_bytecode != Bytecode::null()); - ASSERT(target_bytecode->IsBytecode()); - - const KBCInstr* pc2 = reinterpret_cast( - target_bytecode->ptr()->instructions_); - if (KernelBytecode::IsEntryOptionalOpcode(pc2)) { - pp_ = target_bytecode->ptr()->object_pool_; - uint32_t rA, rB, rC; - rA = KernelBytecode::DecodeA(pc2); - rB = KernelBytecode::DecodeB(pc2); - rC = KernelBytecode::DecodeC(pc2); - pc2 = KernelBytecode::Next(pc2); - if (!CopyParameters(thread, &pc2, &FP, &SP, rA, rB, rC)) { - SP[1] = function; - goto NoSuchMethodFromPrologue; - } - } - - intptr_t len = Smi::Value(checks->ptr()->length_); - SP[1] = checks; - SP[2] = argdesc_; - - const intptr_t type_args_len = - InterpreterHelpers::ArgDescTypeArgsLen(argdesc_); - const intptr_t receiver_idx = type_args_len > 0 ? 1 : 0; - const intptr_t argc = - InterpreterHelpers::ArgDescArgCount(argdesc_) + receiver_idx; - - InstancePtr receiver = - Instance::RawCast(FrameArguments(FP, argc)[receiver_idx]); - SP[5] = InterpreterHelpers::GetTypeArguments(thread, receiver); - - if (type_args_len > 0) { - SP[6] = FrameArguments(FP, argc)[0]; - } else { - SP[6] = TypeArguments::RawCast(checks->ptr()->data()[1]); - // TODO(regis): Verify this condition; why test SP[6]? - if (SP[5] != null_value && SP[6] != null_value) { - SP[7] = SP[6]; // type_arguments - SP[8] = SP[5]; // instantiator_type_args - SP[9] = null_value; // function_type_args - Exit(thread, FP, SP + 10, pc); - INVOKE_RUNTIME(DRT_InstantiateTypeArguments, - NativeArguments(thread, 3, SP + 7, SP + 7)); - SP[6] = SP[7]; - } - } - - for (intptr_t i = 2; i < len; i++) { - ParameterTypeCheckPtr check = - ParameterTypeCheck::RawCast(checks->ptr()->data()[i]); - - if (LIKELY(check->ptr()->index_ != 0)) { - ASSERT(&FP[check->ptr()->index_] <= SP); - SP[3] = Instance::RawCast(FP[check->ptr()->index_]); - // TODO(regis): Revisit null handling once interpreter supports NNBD. - if (SP[3] == null_value) { - continue; // Not handled by AssertAssignable for some reason... - } - SP[4] = check->ptr()->type_or_bound_; - // SP[5]: Instantiator type args. - // SP[6]: Function type args. - SP[7] = check->ptr()->name_; - if (!AssertAssignable(thread, pc, FP, SP + 7, SP + 3, - check->ptr()->cache_)) { - HANDLE_EXCEPTION; - } - } else { - SP[3] = 0; - SP[4] = 0; - // SP[5]: Instantiator type args. - // SP[6]: Function type args. - SP[7] = check->ptr()->param_; - SP[8] = check->ptr()->type_or_bound_; - SP[9] = check->ptr()->name_; - SP[10] = 0; - Exit(thread, FP, SP + 11, pc); - INVOKE_RUNTIME(DRT_SubtypeCheck, - NativeArguments(thread, 5, SP + 5, SP + 10)); - } - - checks = Array::RawCast(SP[1]); // Reload after runtime call. - } - - target = Function::RawCast(checks->ptr()->data()[0]); - argdesc_ = Array::RawCast(SP[2]); - - SP = FP - 1; // Unmarshall optional parameters. - - SP[1] = target; - goto TailCallSP1; - } - - { - BYTECODE(VMInternal_NoSuchMethodDispatcher, 0); - FunctionPtr function = FrameFunction(FP); - ASSERT(Function::kind(function) == FunctionLayout::kNoSuchMethodDispatcher); - SP[1] = function; - goto NoSuchMethodFromPrologue; - } - - { - BYTECODE(VMInternal_ImplicitStaticClosure, 0); - FunctionPtr function = FrameFunction(FP); - ASSERT(Function::kind(function) == - FunctionLayout::kImplicitClosureFunction); - UNIMPLEMENTED(); - DISPATCH(); - } - - { - BYTECODE(VMInternal_ImplicitInstanceClosure, 0); - FunctionPtr function = FrameFunction(FP); - ASSERT(Function::kind(function) == - FunctionLayout::kImplicitClosureFunction); - UNIMPLEMENTED(); - DISPATCH(); - } - - { - TailCallSP1: - FunctionPtr function = Function::RawCast(SP[1]); - - for (;;) { - if (Function::HasBytecode(function)) { - ASSERT(function->IsFunction()); - BytecodePtr bytecode = function->ptr()->bytecode_; - ASSERT(bytecode->IsBytecode()); - FP[kKBCFunctionSlotFromFp] = function; - FP[kKBCPcMarkerSlotFromFp] = bytecode; - pp_ = bytecode->ptr()->object_pool_; - pc = reinterpret_cast(bytecode->ptr()->instructions_); - NOT_IN_PRODUCT(pc_ = pc); // For the profiler. - DISPATCH(); - } - - if (Function::HasCode(function)) { - const intptr_t type_args_len = - InterpreterHelpers::ArgDescTypeArgsLen(argdesc_); - const intptr_t receiver_idx = type_args_len > 0 ? 1 : 0; - const intptr_t argc = - InterpreterHelpers::ArgDescArgCount(argdesc_) + receiver_idx; - ObjectPtr* argv = FrameArguments(FP, argc); - for (intptr_t i = 0; i < argc; i++) { - *++SP = argv[i]; - } - - ObjectPtr* call_base = SP - argc + 1; - ObjectPtr* call_top = SP + 1; - call_top[0] = function; - if (!InvokeCompiled(thread, function, call_base, call_top, &pc, &FP, - &SP)) { - HANDLE_EXCEPTION; - } else { - HANDLE_RETURN; - } - DISPATCH(); - } - - // Compile the function to either generate code or load bytecode. - SP[1] = argdesc_; - SP[2] = 0; // Code result. - SP[3] = function; - Exit(thread, FP, SP + 4, pc); - if (!InvokeRuntime(thread, this, DRT_CompileFunction, - NativeArguments(thread, 1, /* argv */ SP + 3, - /* retval */ SP + 2))) { - HANDLE_EXCEPTION; - } - function = Function::RawCast(SP[3]); - argdesc_ = Array::RawCast(SP[1]); - - ASSERT(Function::HasCode(function) || Function::HasBytecode(function)); - } - } - - // Helper used to handle noSuchMethod on closures. The function should be - // placed into SP[1] before jumping here, similar to TailCallSP1. - { - NoSuchMethodFromPrologue: - FunctionPtr function = Function::RawCast(SP[1]); - - const intptr_t type_args_len = - InterpreterHelpers::ArgDescTypeArgsLen(argdesc_); - const intptr_t receiver_idx = type_args_len > 0 ? 1 : 0; - const intptr_t argc = - InterpreterHelpers::ArgDescArgCount(argdesc_) + receiver_idx; - ObjectPtr* args = FrameArguments(FP, argc); - - SP[1] = null_value; - SP[2] = args[receiver_idx]; - SP[3] = function; - SP[4] = argdesc_; - SP[5] = null_value; // Array of arguments (will be filled). - - // Allocate array of arguments. - { - SP[6] = Smi::New(argc); // length - SP[7] = null_value; // type - Exit(thread, FP, SP + 8, pc); - if (!InvokeRuntime(thread, this, DRT_AllocateArray, - NativeArguments(thread, 2, SP + 6, SP + 5))) { - HANDLE_EXCEPTION; - } - - // Copy arguments into the newly allocated array. - ArrayPtr array = static_cast(SP[5]); - ASSERT(array->GetClassId() == kArrayCid); - for (intptr_t i = 0; i < argc; i++) { - array->ptr()->data()[i] = args[i]; - } - } - - // Invoke noSuchMethod passing down receiver, function, argument descriptor - // and array of arguments. - { - Exit(thread, FP, SP + 6, pc); - INVOKE_RUNTIME(DRT_NoSuchMethodFromPrologue, - NativeArguments(thread, 4, SP + 2, SP + 1)); - ++SP; // Result at SP[0] - } - - DISPATCH(); - } - - { - ThrowNullError: - // SP[0] contains selector. - SP[1] = 0; // Unused space for result. - Exit(thread, FP, SP + 2, pc); - INVOKE_RUNTIME(DRT_NullErrorWithSelector, - NativeArguments(thread, 1, SP, SP + 1)); - UNREACHABLE(); - } - - { - ThrowIntegerDivisionByZeroException: - SP[0] = 0; // Unused space for result. - Exit(thread, FP, SP + 1, pc); - INVOKE_RUNTIME(DRT_IntegerDivisionByZeroException, - NativeArguments(thread, 0, SP, SP)); - UNREACHABLE(); - } - - { - ThrowArgumentError: - // SP[0] contains value. - SP[1] = 0; // Unused space for result. - Exit(thread, FP, SP + 2, pc); - INVOKE_RUNTIME(DRT_ArgumentError, NativeArguments(thread, 1, SP, SP + 1)); - UNREACHABLE(); - } - - // Exception handling helper. Gets handler FP and PC from the Interpreter - // where they were stored by Interpreter::Longjmp and proceeds to execute the - // handler. Corner case: handler PC can be a fake marker that marks entry - // frame, which means exception was not handled in the interpreter. In this - // case we return the caught exception from Interpreter::Call. - { - HandleException: - FP = fp_; - pc = pc_; - if (IsEntryFrameMarker(pc)) { - pp_ = static_cast(fp_[kKBCSavedPpSlotFromEntryFp]); - argdesc_ = static_cast(fp_[kKBCSavedArgDescSlotFromEntryFp]); - uword exit_fp = static_cast(fp_[kKBCExitLinkSlotFromEntryFp]); - thread->set_top_exit_frame_info(exit_fp); - thread->set_top_resource(top_resource); - thread->set_vm_tag(vm_tag); -#if defined(DEBUG) - if (IsTracingExecution()) { - THR_Print("%" Pu64 " ", icount_); - THR_Print("Returning exception from interpreter 0x%" Px " at fp_ 0x%" Px - " exit 0x%" Px "\n", - reinterpret_cast(this), reinterpret_cast(fp_), - exit_fp); - } -#endif - ASSERT(HasFrame(reinterpret_cast(fp_))); - return special_[KernelBytecode::kExceptionSpecialIndex]; - } - - pp_ = InterpreterHelpers::FrameBytecode(FP)->ptr()->object_pool_; - DISPATCH(); - } - - UNREACHABLE(); - return 0; -} - -void Interpreter::JumpToFrame(uword pc, uword sp, uword fp, Thread* thread) { - // Walk over all setjmp buffers (simulated --> C++ transitions) - // and try to find the setjmp associated with the simulated frame pointer. - InterpreterSetjmpBuffer* buf = last_setjmp_buffer(); - while ((buf->link() != NULL) && (buf->link()->fp() > fp)) { - buf = buf->link(); - } - ASSERT(buf != NULL); - ASSERT(last_setjmp_buffer() == buf); - - // The C++ caller has not cleaned up the stack memory of C++ frames. - // Prepare for unwinding frames by destroying all the stack resources - // in the previous C++ frames. - StackResource::Unwind(thread); - - fp_ = reinterpret_cast(fp); - - if (pc == StubCode::RunExceptionHandler().EntryPoint()) { - // The RunExceptionHandler stub is a placeholder. We implement - // its behavior here. - ObjectPtr raw_exception = thread->active_exception(); - ObjectPtr raw_stacktrace = thread->active_stacktrace(); - ASSERT(raw_exception != Object::null()); - thread->set_active_exception(Object::null_object()); - thread->set_active_stacktrace(Object::null_object()); - special_[KernelBytecode::kExceptionSpecialIndex] = raw_exception; - special_[KernelBytecode::kStackTraceSpecialIndex] = raw_stacktrace; - pc_ = reinterpret_cast(thread->resume_pc()); - } else { - pc_ = reinterpret_cast(pc); - } - - // Set the tag. - thread->set_vm_tag(VMTag::kDartInterpretedTagId); - // Clear top exit frame. - thread->set_top_exit_frame_info(0); - - buf->Longjmp(); - UNREACHABLE(); -} - -void Interpreter::VisitObjectPointers(ObjectPointerVisitor* visitor) { - visitor->VisitPointer(reinterpret_cast(&pp_)); - visitor->VisitPointer(reinterpret_cast(&argdesc_)); -} - -} // namespace dart - -#endif // !defined(DART_PRECOMPILED_RUNTIME) diff --git a/runtime/vm/interpreter.h b/runtime/vm/interpreter.h deleted file mode 100644 index bc76fc9ad1e..00000000000 --- a/runtime/vm/interpreter.h +++ /dev/null @@ -1,281 +0,0 @@ -// Copyright (c) 2018, the Dart project authors. Please see the AUTHORS file -// for details. All rights reserved. Use of this source code is governed by a -// BSD-style license that can be found in the LICENSE file. - -#ifndef RUNTIME_VM_INTERPRETER_H_ -#define RUNTIME_VM_INTERPRETER_H_ - -#include "vm/globals.h" -#if !defined(DART_PRECOMPILED_RUNTIME) - -#include "vm/compiler/method_recognizer.h" -#include "vm/constants_kbc.h" -#include "vm/tagged_pointer.h" - -namespace dart { - -class Array; -class Code; -class InterpreterSetjmpBuffer; -class Isolate; -class ObjectPointerVisitor; -class Thread; - -class LookupCache : public ValueObject { - public: - LookupCache() { - ASSERT(Utils::IsPowerOfTwo(sizeof(Entry))); - ASSERT(Utils::IsPowerOfTwo(sizeof(kNumEntries))); - Clear(); - } - - void Clear(); - bool Lookup(intptr_t receiver_cid, - StringPtr function_name, - ArrayPtr arguments_descriptor, - FunctionPtr* target) const; - void Insert(intptr_t receiver_cid, - StringPtr function_name, - ArrayPtr arguments_descriptor, - FunctionPtr target); - - private: - struct Entry { - intptr_t receiver_cid; - StringPtr function_name; - ArrayPtr arguments_descriptor; - FunctionPtr target; - }; - - static const intptr_t kNumEntries = 1024; - static const intptr_t kTableMask = kNumEntries - 1; - - Entry entries_[kNumEntries]; -}; - -// Interpreter intrinsic handler. It is invoked on entry to the intrinsified -// function via Intrinsic bytecode before the frame is setup. -// If the handler returns true then Intrinsic bytecode works as a return -// instruction returning the value in result. Otherwise interpreter proceeds to -// execute the body of the function. -typedef bool (*IntrinsicHandler)(Thread* thread, - ObjectPtr* FP, - ObjectPtr* result); - -class Interpreter { - public: - static const uword kInterpreterStackUnderflowSize = 0x80; - // The entry frame pc marker must be non-zero (a valid exception handler pc). - static const word kEntryFramePcMarker = -1; - - Interpreter(); - ~Interpreter(); - - // The currently executing Interpreter instance, which is associated to the - // current isolate - static Interpreter* Current(); - - // Low address (KBC stack grows up). - uword stack_base() const { return stack_base_; } - // Limit for StackOverflowError. - uword overflow_stack_limit() const { return overflow_stack_limit_; } - // High address (KBC stack grows up). - uword stack_limit() const { return stack_limit_; } - - // Returns true if the interpreter's stack contains the given frame. - // TODO(regis): We should rely on a new thread vm_tag to identify an - // interpreter frame and not need this HasFrame() method. - bool HasFrame(uword frame) const { - return frame >= stack_base() && frame < stack_limit(); - } - - // Identify an entry frame by looking at its pc marker value. - static bool IsEntryFrameMarker(const KBCInstr* pc) { - return reinterpret_cast(pc) == kEntryFramePcMarker; - } - - ObjectPtr Call(const Function& function, - const Array& arguments_descriptor, - const Array& arguments, - Thread* thread); - - ObjectPtr Call(FunctionPtr function, - ArrayPtr argdesc, - intptr_t argc, - ObjectPtr const* argv, - Thread* thread); - - void JumpToFrame(uword pc, uword sp, uword fp, Thread* thread); - - uword get_sp() const { return reinterpret_cast(fp_); } // Yes, fp_. - uword get_fp() const { return reinterpret_cast(fp_); } - uword get_pc() const { return reinterpret_cast(pc_); } - - void Unexit(Thread* thread); - - void VisitObjectPointers(ObjectPointerVisitor* visitor); - void ClearLookupCache() { lookup_cache_.Clear(); } - -#ifndef PRODUCT - void set_is_debugging(bool value) { is_debugging_ = value; } - bool is_debugging() const { return is_debugging_; } -#endif // !PRODUCT - - private: - uintptr_t* stack_; - uword stack_base_; - uword overflow_stack_limit_; - uword stack_limit_; - - ObjectPtr* volatile fp_; - const KBCInstr* volatile pc_; - DEBUG_ONLY(uint64_t icount_;) - - InterpreterSetjmpBuffer* last_setjmp_buffer_; - - ObjectPoolPtr pp_; // Pool Pointer. - ArrayPtr argdesc_; // Arguments Descriptor: used to pass information between - // call instruction and the function entry. - ObjectPtr special_[KernelBytecode::kSpecialIndexCount]; - - LookupCache lookup_cache_; - - void Exit(Thread* thread, - ObjectPtr* base, - ObjectPtr* exit_frame, - const KBCInstr* pc); - - bool Invoke(Thread* thread, - ObjectPtr* call_base, - ObjectPtr* call_top, - const KBCInstr** pc, - ObjectPtr** FP, - ObjectPtr** SP); - - bool InvokeCompiled(Thread* thread, - FunctionPtr function, - ObjectPtr* call_base, - ObjectPtr* call_top, - const KBCInstr** pc, - ObjectPtr** FP, - ObjectPtr** SP); - - bool InvokeBytecode(Thread* thread, - FunctionPtr function, - ObjectPtr* call_base, - ObjectPtr* call_top, - const KBCInstr** pc, - ObjectPtr** FP, - ObjectPtr** SP); - - bool InstanceCall(Thread* thread, - StringPtr target_name, - ObjectPtr* call_base, - ObjectPtr* call_top, - const KBCInstr** pc, - ObjectPtr** FP, - ObjectPtr** SP); - - bool CopyParameters(Thread* thread, - const KBCInstr** pc, - ObjectPtr** FP, - ObjectPtr** SP, - const intptr_t num_fixed_params, - const intptr_t num_opt_pos_params, - const intptr_t num_opt_named_params); - - bool AssertAssignable(Thread* thread, - const KBCInstr* pc, - ObjectPtr* FP, - ObjectPtr* call_top, - ObjectPtr* args, - SubtypeTestCachePtr cache); - template - bool AssertAssignableField(Thread* thread, - const KBCInstr* pc, - ObjectPtr* FP, - ObjectPtr* SP, - InstancePtr instance, - FieldPtr field, - InstancePtr value); - - bool AllocateMint(Thread* thread, - int64_t value, - const KBCInstr* pc, - ObjectPtr* FP, - ObjectPtr* SP); - bool AllocateDouble(Thread* thread, - double value, - const KBCInstr* pc, - ObjectPtr* FP, - ObjectPtr* SP); - bool AllocateFloat32x4(Thread* thread, - simd128_value_t value, - const KBCInstr* pc, - ObjectPtr* FP, - ObjectPtr* SP); - bool AllocateFloat64x2(Thread* thread, - simd128_value_t value, - const KBCInstr* pc, - ObjectPtr* FP, - ObjectPtr* SP); - bool AllocateArray(Thread* thread, - TypeArgumentsPtr type_args, - ObjectPtr length, - const KBCInstr* pc, - ObjectPtr* FP, - ObjectPtr* SP); - bool AllocateContext(Thread* thread, - intptr_t num_variables, - const KBCInstr* pc, - ObjectPtr* FP, - ObjectPtr* SP); - bool AllocateClosure(Thread* thread, - const KBCInstr* pc, - ObjectPtr* FP, - ObjectPtr* SP); - -#if defined(DEBUG) - // Returns true if tracing of executed instructions is enabled. - bool IsTracingExecution() const; - - // Prints bytecode instruction at given pc for instruction tracing. - void TraceInstruction(const KBCInstr* pc) const; - - bool IsWritingTraceFile() const; - void FlushTraceBuffer(); - void WriteInstructionToTrace(const KBCInstr* pc); - - void* trace_file_; - uint64_t trace_file_bytes_written_; - - static const intptr_t kTraceBufferSizeInBytes = 10 * KB; - static const intptr_t kTraceBufferInstrs = - kTraceBufferSizeInBytes / sizeof(KBCInstr); - KBCInstr* trace_buffer_; - intptr_t trace_buffer_idx_; -#endif // defined(DEBUG) - - // Longjmp support for exceptions. - InterpreterSetjmpBuffer* last_setjmp_buffer() { return last_setjmp_buffer_; } - void set_last_setjmp_buffer(InterpreterSetjmpBuffer* buffer) { - last_setjmp_buffer_ = buffer; - } - -#ifndef PRODUCT - bool is_debugging_ = false; -#endif // !PRODUCT - - bool supports_unboxed_doubles_; - bool supports_unboxed_simd128_; - - friend class InterpreterSetjmpBuffer; - - DISALLOW_COPY_AND_ASSIGN(Interpreter); -}; - -} // namespace dart - -#endif // !defined(DART_PRECOMPILED_RUNTIME) - -#endif // RUNTIME_VM_INTERPRETER_H_ diff --git a/runtime/vm/isolate.cc b/runtime/vm/isolate.cc index 3f7e0023615..8b8bbc08e89 100644 --- a/runtime/vm/isolate.cc +++ b/runtime/vm/isolate.cc @@ -26,7 +26,6 @@ #include "vm/heap/safepoint.h" #include "vm/heap/verifier.h" #include "vm/image_snapshot.h" -#include "vm/interpreter.h" #include "vm/isolate_reload.h" #include "vm/kernel_isolate.h" #include "vm/lockers.h" @@ -1681,10 +1680,6 @@ Isolate::Isolate(IsolateGroup* isolate_group, " See dartbug.com/30524 for more information.\n"); } - if (FLAG_enable_interpreter) { - NOT_IN_PRECOMPILED(background_compiler_ = new BackgroundCompiler( - this, /* optimizing = */ false)); - } NOT_IN_PRECOMPILED(optimizing_background_compiler_ = new BackgroundCompiler(this, /* optimizing = */ true)); } @@ -1698,11 +1693,6 @@ Isolate::~Isolate() { // RELEASE_ASSERT(reload_context_ == NULL); #endif // !defined(PRODUCT) && !defined(DART_PRECOMPILED_RUNTIME) - if (FLAG_enable_interpreter) { - delete background_compiler_; - background_compiler_ = nullptr; - } - delete optimizing_background_compiler_; optimizing_background_compiler_ = nullptr; @@ -2602,10 +2592,6 @@ void Isolate::set_forward_table_old(WeakTable* table) { void Isolate::Shutdown() { ASSERT(this == Isolate::Current()); BackgroundCompiler::Stop(this); - if (FLAG_enable_interpreter) { - delete background_compiler_; - background_compiler_ = nullptr; - } delete optimizing_background_compiler_; optimizing_background_compiler_ = nullptr; diff --git a/runtime/vm/isolate.h b/runtime/vm/isolate.h index 68c72ed0a99..0d3279d6a41 100644 --- a/runtime/vm/isolate.h +++ b/runtime/vm/isolate.h @@ -18,7 +18,6 @@ #include "platform/atomic.h" #include "vm/base_isolate.h" #include "vm/class_table.h" -#include "vm/constants_kbc.h" #include "vm/dispatch_table.h" #include "vm/exceptions.h" #include "vm/field_table.h" @@ -56,9 +55,6 @@ class HandleScope; class HandleVisitor; class Heap; class ICData; -#if !defined(DART_PRECOMPILED_RUNTIME) -class Interpreter; -#endif class IsolateObjectStore; class IsolateProfilerData; class IsolateReloadContext; diff --git a/runtime/vm/isolate_reload.cc b/runtime/vm/isolate_reload.cc index 005a2e9a767..f9e26a04bdd 100644 --- a/runtime/vm/isolate_reload.cc +++ b/runtime/vm/isolate_reload.cc @@ -1221,7 +1221,7 @@ void IsolateReloadContext::EnsuredUnoptimizedCodeForStack() { Function& func = Function::Handle(); while (it.HasNextFrame()) { StackFrame* frame = it.NextFrame(); - if (frame->IsDartFrame() && !frame->is_interpreted()) { + if (frame->IsDartFrame()) { func = frame->LookupDartFunction(); ASSERT(!func.IsNull()); // Force-optimized functions don't need unoptimized code because their @@ -1945,31 +1945,25 @@ void IsolateReloadContext::ResetUnoptimizedICsOnStack() { Zone* zone = stack_zone.GetZone(); Code& code = Code::Handle(zone); - Bytecode& bytecode = Bytecode::Handle(zone); Function& function = Function::Handle(zone); CallSiteResetter resetter(zone); DartFrameIterator iterator(thread, StackFrameIterator::kNoCrossThreadIteration); StackFrame* frame = iterator.NextFrame(); while (frame != NULL) { - if (frame->is_interpreted()) { - bytecode = frame->LookupDartBytecode(); - resetter.RebindStaticTargets(bytecode); + code = frame->LookupDartCode(); + if (code.is_optimized() && !code.is_force_optimized()) { + // If this code is optimized, we need to reset the ICs in the + // corresponding unoptimized code, which will be executed when the stack + // unwinds to the optimized code. + function = code.function(); + code = function.unoptimized_code(); + ASSERT(!code.IsNull()); + resetter.ResetSwitchableCalls(code); + resetter.ResetCaches(code); } else { - code = frame->LookupDartCode(); - if (code.is_optimized() && !code.is_force_optimized()) { - // If this code is optimized, we need to reset the ICs in the - // corresponding unoptimized code, which will be executed when the stack - // unwinds to the optimized code. - function = code.function(); - code = function.unoptimized_code(); - ASSERT(!code.IsNull()); - resetter.ResetSwitchableCalls(code); - resetter.ResetCaches(code); - } else { - resetter.ResetSwitchableCalls(code); - resetter.ResetCaches(code); - } + resetter.ResetSwitchableCalls(code); + resetter.ResetCaches(code); } frame = iterator.NextFrame(); } @@ -2032,14 +2026,6 @@ void IsolateReloadContext::RunInvalidationVisitors() { StackZone stack_zone(thread); Zone* zone = stack_zone.GetZone(); - Thread* mutator_thread = I->mutator_thread(); - if (mutator_thread != nullptr) { - Interpreter* interpreter = mutator_thread->interpreter(); - if (interpreter != nullptr) { - interpreter->ClearLookupCache(); - } - } - GrowableArray functions(4 * KB); GrowableArray kernel_infos(KB); GrowableArray fields(4 * KB); @@ -2084,10 +2070,6 @@ void IsolateReloadContext::InvalidateKernelInfos( table.Clear(); info.set_classes_cache(table.Release()); } - // Clear the bytecode object table. - if (info.bytecode_component() != Array::null()) { - kernel::BytecodeReader::ResetObjectTable(info); - } } } @@ -2102,7 +2084,6 @@ void IsolateReloadContext::InvalidateFunctions( Class& owning_class = Class::Handle(zone); Library& owning_lib = Library::Handle(zone); Code& code = Code::Handle(zone); - Bytecode& bytecode = Bytecode::Handle(zone); for (intptr_t i = 0; i < functions.length(); i++) { const Function& func = *functions[i]; if (func.IsSignatureFunction()) { @@ -2115,7 +2096,6 @@ void IsolateReloadContext::InvalidateFunctions( // Grab the current code. code = func.CurrentCode(); ASSERT(!code.IsNull()); - bytecode = func.bytecode(); owning_class = func.Owner(); owning_lib = owning_class.library(); @@ -2126,10 +2106,6 @@ void IsolateReloadContext::InvalidateFunctions( // they're held. resetter.ZeroEdgeCounters(func); - if (!bytecode.IsNull()) { - resetter.RebindStaticTargets(bytecode); - } - if (stub_code) { // Nothing to reset. } else if (clear_code) { diff --git a/runtime/vm/isolate_reload.h b/runtime/vm/isolate_reload.h index b06ca57d3e4..ad29eb0e513 100644 --- a/runtime/vm/isolate_reload.h +++ b/runtime/vm/isolate_reload.h @@ -435,7 +435,6 @@ class CallSiteResetter : public ValueObject { void ZeroEdgeCounters(const Function& function); void ResetCaches(const Code& code); void ResetCaches(const ObjectPool& pool); - void RebindStaticTargets(const Bytecode& code); void Reset(const ICData& ic); void ResetSwitchableCalls(const Code& code); diff --git a/runtime/vm/kernel.cc b/runtime/vm/kernel.cc index 7dc10963037..23e5ce87220 100644 --- a/runtime/vm/kernel.cc +++ b/runtime/vm/kernel.cc @@ -7,7 +7,6 @@ #include "vm/kernel.h" #include "vm/bit_vector.h" -#include "vm/compiler/frontend/bytecode_reader.h" #include "vm/compiler/frontend/constant_reader.h" #include "vm/compiler/frontend/kernel_translation_helper.h" #include "vm/compiler/jit/compiler.h" @@ -230,71 +229,6 @@ static void CollectKernelDataTokenPositions( token_position_collector.CollectTokenPositions(kernel_offset); } -static void CollectTokenPosition(TokenPosition position, - GrowableArray* token_positions) { - if (position.IsReal()) { - token_positions->Add(position.value()); - } -} - -static void CollectBytecodeSourceTokenPositions( - const Bytecode& bytecode, - Zone* zone, - GrowableArray* token_positions) { - BytecodeSourcePositionsIterator iter(zone, bytecode); - while (iter.MoveNext()) { - CollectTokenPosition(iter.TokenPos(), token_positions); - } -} - -static void CollectBytecodeFunctionTokenPositions( - const Function& function, - GrowableArray* token_positions) { - Thread* thread = Thread::Current(); - Zone* zone = thread->zone(); - ASSERT(function.is_declared_in_bytecode()); - CollectTokenPosition(function.token_pos(), token_positions); - CollectTokenPosition(function.end_token_pos(), token_positions); - if (!function.HasBytecode()) { - const Object& result = Object::Handle( - zone, BytecodeReader::ReadFunctionBytecode(thread, function)); - if (!result.IsNull()) { - Exceptions::PropagateError(Error::Cast(result)); - } - } - Bytecode& bytecode = Bytecode::Handle(zone, function.bytecode()); - if (bytecode.IsNull()) { - return; - } - if (bytecode.HasSourcePositions() && !function.IsLocalFunction()) { - CollectBytecodeSourceTokenPositions(bytecode, zone, token_positions); - // Find closure functions in the object pool. - const ObjectPool& pool = ObjectPool::Handle(zone, bytecode.object_pool()); - Object& object = Object::Handle(zone); - Function& closure = Function::Handle(zone); - for (intptr_t i = 0; i < pool.Length(); i++) { - ObjectPool::EntryType entry_type = pool.TypeAt(i); - if (entry_type != ObjectPool::EntryType::kTaggedObject) { - continue; - } - object = pool.ObjectAt(i); - if (object.IsFunction()) { - closure ^= object.raw(); - if (closure.kind() == FunctionLayout::kClosureFunction && - closure.IsLocalFunction()) { - CollectTokenPosition(closure.token_pos(), token_positions); - CollectTokenPosition(closure.end_token_pos(), token_positions); - bytecode = closure.bytecode(); - ASSERT(!bytecode.IsNull()); - ASSERT(bytecode.function() != Function::null()); - ASSERT(bytecode.HasSourcePositions()); - CollectBytecodeSourceTokenPositions(bytecode, zone, token_positions); - } - } - } - } -} - void CollectTokenPositionsFor(const Script& interesting_script) { Thread* thread = Thread::Current(); Zone* zone = thread->zone(); @@ -328,22 +262,11 @@ void CollectTokenPositionsFor(const Script& interesting_script) { token_positions.Add(klass.token_pos().value()); token_positions.Add(klass.end_token_pos().value()); } - // If class is declared in bytecode, its members should be loaded - // (via class finalization) before their token positions could be - // collected. - if (klass.is_declared_in_bytecode() && !klass.is_finalized()) { - const Error& error = - Error::Handle(zone, klass.EnsureIsFinalized(thread)); - if (!error.IsNull()) { - Exceptions::PropagateError(error); - } - } if (klass.is_finalized()) { temp_array = klass.fields(); for (intptr_t i = 0; i < temp_array.Length(); ++i) { temp_field ^= temp_array.At(i); - if (!temp_field.is_declared_in_bytecode() && - temp_field.kernel_offset() <= 0) { + if (temp_field.kernel_offset() <= 0) { // Skip artificially injected fields. continue; } @@ -351,23 +274,12 @@ void CollectTokenPositionsFor(const Script& interesting_script) { if (entry_script.raw() != interesting_script.raw()) { continue; } - if (temp_field.is_declared_in_bytecode()) { - token_positions.Add(temp_field.token_pos().value()); - token_positions.Add(temp_field.end_token_pos().value()); - if (temp_field.is_static() && - temp_field.has_nontrivial_initializer()) { - temp_function = temp_field.EnsureInitializerFunction(); - CollectBytecodeFunctionTokenPositions(temp_function, - &token_positions); - } - } else { - data = temp_field.KernelData(); - CollectKernelDataTokenPositions( - data, interesting_script, entry_script, - temp_field.kernel_offset(), - temp_field.KernelDataProgramOffset(), zone, &helper, - &token_positions); - } + data = temp_field.KernelData(); + CollectKernelDataTokenPositions( + data, interesting_script, entry_script, + temp_field.kernel_offset(), + temp_field.KernelDataProgramOffset(), zone, &helper, + &token_positions); } temp_array = klass.current_functions(); for (intptr_t i = 0; i < temp_array.Length(); ++i) { @@ -376,21 +288,15 @@ void CollectTokenPositionsFor(const Script& interesting_script) { if (entry_script.raw() != interesting_script.raw()) { continue; } - if (temp_function.is_declared_in_bytecode()) { - CollectBytecodeFunctionTokenPositions(temp_function, - &token_positions); - } else { - data = temp_function.KernelData(); - CollectKernelDataTokenPositions( - data, interesting_script, entry_script, - temp_function.kernel_offset(), - temp_function.KernelDataProgramOffset(), zone, &helper, - &token_positions); - } + data = temp_function.KernelData(); + CollectKernelDataTokenPositions( + data, interesting_script, entry_script, + temp_function.kernel_offset(), + temp_function.KernelDataProgramOffset(), zone, &helper, + &token_positions); } } else { // Class isn't finalized yet: read the data attached to it. - ASSERT(!klass.is_declared_in_bytecode()); ASSERT(klass.kernel_offset() > 0); data = lib.kernel_data(); ASSERT(!data.IsNull()); @@ -412,20 +318,14 @@ void CollectTokenPositionsFor(const Script& interesting_script) { if (entry_script.raw() != interesting_script.raw()) { continue; } - if (temp_function.is_declared_in_bytecode()) { - CollectBytecodeFunctionTokenPositions(temp_function, - &token_positions); - } else { - data = temp_function.KernelData(); - CollectKernelDataTokenPositions( - data, interesting_script, entry_script, - temp_function.kernel_offset(), - temp_function.KernelDataProgramOffset(), zone, &helper, - &token_positions); - } + data = temp_function.KernelData(); + CollectKernelDataTokenPositions(data, interesting_script, entry_script, + temp_function.kernel_offset(), + temp_function.KernelDataProgramOffset(), + zone, &helper, &token_positions); } else if (entry.IsField()) { const Field& field = Field::Cast(entry); - if (!field.is_declared_in_bytecode() && field.kernel_offset() <= 0) { + if (field.kernel_offset() <= 0) { // Skip artificially injected fields. continue; } @@ -433,20 +333,10 @@ void CollectTokenPositionsFor(const Script& interesting_script) { if (entry_script.raw() != interesting_script.raw()) { continue; } - if (field.is_declared_in_bytecode()) { - token_positions.Add(field.token_pos().value()); - token_positions.Add(field.end_token_pos().value()); - if (field.is_static() && field.has_nontrivial_initializer()) { - temp_function = field.EnsureInitializerFunction(); - CollectBytecodeFunctionTokenPositions(temp_function, - &token_positions); - } - } else { - data = field.KernelData(); - CollectKernelDataTokenPositions( - data, interesting_script, entry_script, field.kernel_offset(), - field.KernelDataProgramOffset(), zone, &helper, &token_positions); - } + data = field.KernelData(); + CollectKernelDataTokenPositions( + data, interesting_script, entry_script, field.kernel_offset(), + field.KernelDataProgramOffset(), zone, &helper, &token_positions); } } } @@ -627,15 +517,6 @@ ObjectPtr BuildParameterDescriptor(const Function& function) { Script& script = Script::Handle(zone, function.script()); helper.InitFromScript(script); - if (function.is_declared_in_bytecode()) { - BytecodeComponentData bytecode_component( - &Array::Handle(zone, helper.GetBytecodeComponent())); - ActiveClass active_class; - BytecodeReaderHelper bytecode_reader_helper(&helper, &active_class, - &bytecode_component); - return bytecode_reader_helper.BuildParameterDescriptor(function); - } - const Class& owner_class = Class::Handle(zone, function.Owner()); ActiveClass active_class; ActiveClassScope active_class_scope(&active_class, &owner_class); @@ -665,14 +546,6 @@ void ReadParameterCovariance(const Function& function, TranslationHelper translation_helper(thread); translation_helper.InitFromScript(script); - if (function.is_declared_in_bytecode()) { - BytecodeReaderHelper bytecode_reader_helper(&translation_helper, nullptr, - nullptr); - bytecode_reader_helper.ReadParameterCovariance(function, is_covariant, - is_generic_covariant_impl); - return; - } - KernelReaderHelper reader_helper( zone, &translation_helper, script, ExternalTypedData::Handle(zone, function.KernelData()), @@ -809,55 +682,8 @@ static ProcedureAttributesMetadata ProcedureAttributesOf( return attrs; } -static void BytecodeProcedureAttributesError(const Object& function_or_field, - const Object& value) { - FATAL3("Unexpected value of %s bytecode attribute on %s: %s", - Symbols::vm_procedure_attributes_metadata().ToCString(), - function_or_field.ToCString(), value.ToCString()); -} - -static ProcedureAttributesMetadata ProcedureAttributesFromBytecodeAttribute( - Zone* zone, - const Object& function_or_field) { - ProcedureAttributesMetadata attrs; - const Object& value = Object::Handle( - zone, - BytecodeReader::GetBytecodeAttribute( - function_or_field, Symbols::vm_procedure_attributes_metadata())); - if (!value.IsNull()) { - const intptr_t kBytecodeAttributeLength = 3; - int32_t elements[kBytecodeAttributeLength]; - if (!value.IsArray()) { - BytecodeProcedureAttributesError(function_or_field, value); - } - const Array& array = Array::Cast(value); - if (array.Length() != kBytecodeAttributeLength) { - BytecodeProcedureAttributesError(function_or_field, value); - } - Object& element = Object::Handle(zone); - for (intptr_t i = 0; i < kBytecodeAttributeLength; i++) { - element = array.At(i); - if (!element.IsSmi()) { - BytecodeProcedureAttributesError(function_or_field, value); - } - elements[i] = Smi::Cast(element).Value(); - } - attrs.InitializeFromFlags(elements[0]); - attrs.method_or_setter_selector_id = elements[1]; - attrs.getter_selector_id = elements[2]; - } - return attrs; -} - ProcedureAttributesMetadata ProcedureAttributesOf(const Function& function, Zone* zone) { - if (function.is_declared_in_bytecode()) { - if (function.IsImplicitGetterOrSetter()) { - const Field& field = Field::Handle(zone, function.accessor_field()); - return ProcedureAttributesFromBytecodeAttribute(zone, field); - } - return ProcedureAttributesFromBytecodeAttribute(zone, function); - } const Script& script = Script::Handle(zone, function.script()); return ProcedureAttributesOf( zone, script, ExternalTypedData::Handle(zone, function.KernelData()), @@ -866,9 +692,6 @@ ProcedureAttributesMetadata ProcedureAttributesOf(const Function& function, ProcedureAttributesMetadata ProcedureAttributesOf(const Field& field, Zone* zone) { - if (field.is_declared_in_bytecode()) { - return ProcedureAttributesFromBytecodeAttribute(zone, field); - } const Class& parent = Class::Handle(zone, field.Owner()); const Script& script = Script::Handle(zone, parent.script()); return ProcedureAttributesOf( diff --git a/runtime/vm/kernel.h b/runtime/vm/kernel.h index 2ac42a1b311..c31b0456059 100644 --- a/runtime/vm/kernel.h +++ b/runtime/vm/kernel.h @@ -214,11 +214,6 @@ void ReadParameterCovariance(const Function& function, // as such function already checks all of its parameters. bool NeedsDynamicInvocationForwarder(const Function& function); -// Returns a list of ParameterTypeChecks needed by a dynamic invocation -// forwarder that targets [function]. Indices in these checks correspond to -// bytecode frame indices. -ArrayPtr CollectDynamicInvocationChecks(const Function& function); - ProcedureAttributesMetadata ProcedureAttributesOf(const Function& function, Zone* zone); diff --git a/runtime/vm/kernel_isolate.cc b/runtime/vm/kernel_isolate.cc index d2cdbb569d0..3b34856ad31 100644 --- a/runtime/vm/kernel_isolate.cc +++ b/runtime/vm/kernel_isolate.cc @@ -647,11 +647,6 @@ class KernelCompilationRequest : public ValueObject { experimental_flags_object.value.as_array.values = experimental_flags_array; experimental_flags_object.value.as_array.length = num_experimental_flags; - Dart_CObject bytecode; - bytecode.type = Dart_CObject_kBool; - bytecode.value.as_bool = - FLAG_enable_interpreter || FLAG_use_bytecode_compiler; - Dart_CObject message; message.type = Dart_CObject_kArray; Dart_CObject* message_arr[] = {&tag, @@ -668,8 +663,7 @@ class KernelCompilationRequest : public ValueObject { &num_blob_loads, &suppress_warnings, &enable_asserts, - &experimental_flags_object, - &bytecode}; + &experimental_flags_object}; message.value.as_array.values = message_arr; message.value.as_array.length = ARRAY_SIZE(message_arr); @@ -813,11 +807,6 @@ class KernelCompilationRequest : public ValueObject { experimental_flags_object.value.as_array.values = experimental_flags_array; experimental_flags_object.value.as_array.length = num_experimental_flags; - Dart_CObject bytecode; - bytecode.type = Dart_CObject_kBool; - bytecode.value.as_bool = - FLAG_enable_interpreter || FLAG_use_bytecode_compiler; - Dart_CObject package_config_uri; if (package_config != NULL) { package_config_uri.type = Dart_CObject_kString; @@ -875,7 +864,6 @@ class KernelCompilationRequest : public ValueObject { &suppress_warnings, &enable_asserts, &experimental_flags_object, - &bytecode, &package_config_uri, &multiroot_filepaths_object, &multiroot_scheme_object, diff --git a/runtime/vm/kernel_loader.cc b/runtime/vm/kernel_loader.cc index 5b5ea0d44cf..e3860d073ee 100644 --- a/runtime/vm/kernel_loader.cc +++ b/runtime/vm/kernel_loader.cc @@ -210,7 +210,6 @@ KernelLoader::KernelLoader(Program* program, &active_class_, /* finalize= */ false), inferred_type_metadata_helper_(&helper_, &constant_reader_), - bytecode_metadata_helper_(&helper_, &active_class_), external_name_class_(Class::Handle(Z)), external_name_field_(Field::Handle(Z)), potential_natives_(GrowableObjectArray::Handle(Z)), @@ -450,8 +449,6 @@ void KernelLoader::InitializeFields(UriToSourceTable* uri_to_source_table) { script = LoadScriptAt(index, uri_to_source_table); scripts.SetAt(index, script); } - - bytecode_metadata_helper_.ReadBytecodeComponent(); } KernelLoader::KernelLoader(const Script& script, @@ -478,7 +475,6 @@ KernelLoader::KernelLoader(const Script& script, &active_class_, /* finalize= */ false), inferred_type_metadata_helper_(&helper_, &constant_reader_), - bytecode_metadata_helper_(&helper_, &active_class_), external_name_class_(Class::Handle(Z)), external_name_field_(Field::Handle(Z)), potential_natives_(GrowableObjectArray::Handle(Z)), @@ -653,64 +649,49 @@ void KernelLoader::LoadNativeExtensionLibraries() { for (intptr_t i = 0; i < length; ++i) { library ^= potential_extension_libraries.At(i); - if (library.is_declared_in_bytecode()) { - const auto& imports = Array::Handle(Z, library.imports()); - auto& ns = Namespace::Handle(Z); - auto& importee = Library::Handle(Z); - for (intptr_t j = 0; j < imports.Length(); ++j) { - ns ^= imports.At(j); - if (ns.IsNull()) continue; - importee = ns.library(); - uri_path = importee.url(); - if (uri_path.StartsWith(Symbols::DartExtensionScheme())) { - LoadNativeExtension(library, uri_path); + helper_.SetOffset(library.kernel_offset()); + + LibraryHelper library_helper(&helper_, kernel_binary_version_); + library_helper.ReadUntilExcluding(LibraryHelper::kAnnotations); + + const intptr_t annotation_count = helper_.ReadListLength(); + for (intptr_t j = 0; j < annotation_count; ++j) { + uri_path = String::null(); + + const intptr_t tag = helper_.PeekTag(); + if (tag == kConstantExpression) { + helper_.ReadByte(); // Skip the tag. + helper_.ReadPosition(); // Skip fileOffset. + helper_.SkipDartType(); // Skip type. + + // We have a candidate. Let's look if it's an instance of the + // ExternalName class. + const intptr_t constant_table_offset = helper_.ReadUInt(); + if (constant_reader.IsInstanceConstant(constant_table_offset, + external_name_class_)) { + constant = constant_reader.ReadConstant(constant_table_offset); + ASSERT(constant.clazz() == external_name_class_.raw()); + uri_path ^= constant.GetField(external_name_field_); } + } else if (tag == kConstructorInvocation || + tag == kConstConstructorInvocation) { + uri_path = DetectExternalNameCtor(); + } else { + helper_.SkipExpression(); } - } else { - helper_.SetOffset(library.kernel_offset()); - LibraryHelper library_helper(&helper_, kernel_binary_version_); - library_helper.ReadUntilExcluding(LibraryHelper::kAnnotations); + if (uri_path.IsNull()) continue; - const intptr_t annotation_count = helper_.ReadListLength(); - for (intptr_t j = 0; j < annotation_count; ++j) { - uri_path = String::null(); + LoadNativeExtension(library, uri_path); - const intptr_t tag = helper_.PeekTag(); - if (tag == kConstantExpression) { - helper_.ReadByte(); // Skip the tag. - helper_.ReadPosition(); // Skip fileOffset. - helper_.SkipDartType(); // Skip type. - - // We have a candidate. Let's look if it's an instance of the - // ExternalName class. - const intptr_t constant_table_offset = helper_.ReadUInt(); - if (constant_reader.IsInstanceConstant(constant_table_offset, - external_name_class_)) { - constant = constant_reader.ReadConstant(constant_table_offset); - ASSERT(constant.clazz() == external_name_class_.raw()); - uri_path ^= constant.GetField(external_name_field_); - } - } else if (tag == kConstructorInvocation || - tag == kConstConstructorInvocation) { - uri_path = DetectExternalNameCtor(); - } else { - helper_.SkipExpression(); - } - - if (uri_path.IsNull()) continue; - - LoadNativeExtension(library, uri_path); - - // Create a dummy library and add it as an import to the current - // library. This allows later to discover and reload this native - // extension, e.g. when running from an app-jit snapshot. - // See Loader::ReloadNativeExtensions(...) which relies on - // Dart_GetImportsOfScheme('dart-ext'). - const auto& native_library = Library::Handle(Library::New(uri_path)); - library.AddImport(Namespace::Handle(Namespace::New( - native_library, Array::null_array(), Array::null_array()))); - } + // Create a dummy library and add it as an import to the current + // library. This allows later to discover and reload this native + // extension, e.g. when running from an app-jit snapshot. + // See Loader::ReloadNativeExtensions(...) which relies on + // Dart_GetImportsOfScheme('dart-ext'). + const auto& native_library = Library::Handle(Library::New(uri_path)); + library.AddImport(Namespace::Handle(Namespace::New( + native_library, Array::null_array(), Array::null_array()))); } } } @@ -745,12 +726,10 @@ ObjectPtr KernelLoader::LoadProgram(bool process_pending_classes) { LongJumpScope jump; if (setjmp(*jump.Set()) == 0) { - if (!bytecode_metadata_helper_.ReadLibraries()) { - // Note that `problemsAsJson` on Component is implicitly skipped. - const intptr_t length = program_->library_count(); - for (intptr_t i = 0; i < length; i++) { - LoadLibrary(i); - } + // Note that `problemsAsJson` on Component is implicitly skipped. + const intptr_t length = program_->library_count(); + for (intptr_t i = 0; i < length; i++) { + LoadLibrary(i); } // Finalize still pending classes if requested. @@ -780,7 +759,7 @@ ObjectPtr KernelLoader::LoadProgram(bool process_pending_classes) { return LookupLibrary(main_library); } - return bytecode_metadata_helper_.GetMainLibrary(); + return Library::null(); } // Either class finalization failed or we caught a compile error. @@ -791,10 +770,6 @@ ObjectPtr KernelLoader::LoadProgram(bool process_pending_classes) { void KernelLoader::LoadLibrary(const Library& library) { ASSERT(!library.Loaded()); - bytecode_metadata_helper_.ReadLibrary(library); - if (library.Loaded()) { - return; - } const auto& uri = String::Handle(Z, library.url()); const intptr_t num_libraries = program_->library_count(); for (intptr_t i = 0; i < num_libraries; ++i) { @@ -840,13 +815,10 @@ ObjectPtr KernelLoader::LoadExpressionEvaluationFunction( // Make the expression evaluation function have the right script, // kernel data and parent. const auto& eval_script = Script::Handle(Z, function.script()); - auto& kernel_data = ExternalTypedData::Handle(Z); - intptr_t kernel_offset = -1; - if (!function.is_declared_in_bytecode()) { - ASSERT(!expression_evaluation_library_.IsNull()); - kernel_data = expression_evaluation_library_.kernel_data(); - kernel_offset = expression_evaluation_library_.kernel_offset(); - } + ASSERT(!expression_evaluation_library_.IsNull()); + auto& kernel_data = ExternalTypedData::Handle( + Z, expression_evaluation_library_.kernel_data()); + intptr_t kernel_offset = expression_evaluation_library_.kernel_offset(); function.SetKernelDataAndScript(eval_script, kernel_data, kernel_offset); function.set_owner(real_class); @@ -924,10 +896,6 @@ void KernelLoader::walk_incremental_kernel(BitVector* modified_libs, bool* is_empty_program, intptr_t* p_num_classes, intptr_t* p_num_procedures) { - if (bytecode_metadata_helper_.FindModifiedLibrariesForHotReload( - modified_libs, is_empty_program, p_num_classes, p_num_procedures)) { - return; - } intptr_t length = program_->library_count(); *is_empty_program = *is_empty_program && (length == 0); bool collect_library_stats = @@ -1146,7 +1114,7 @@ LibraryPtr KernelLoader::LoadLibrary(intptr_t index) { if (FLAG_enable_mirrors && annotation_count > 0) { ASSERT(annotations_kernel_offset > 0); library.AddLibraryMetadata(toplevel_class, TokenPosition::kNoSource, - annotations_kernel_offset, 0); + annotations_kernel_offset); } if (register_class) { @@ -1267,8 +1235,7 @@ void KernelLoader::FinishTopLevelClassLoading( } if ((FLAG_enable_mirrors || has_pragma_annotation) && annotation_count > 0) { - library.AddFieldMetadata(field, TokenPosition::kNoSource, field_offset, - 0); + library.AddFieldMetadata(field, TokenPosition::kNoSource, field_offset); } fields_.Add(&field); } @@ -1533,7 +1500,7 @@ void KernelLoader::LoadClass(const Library& library, if ((FLAG_enable_mirrors || has_pragma_annotation) && annotation_count > 0) { library.AddClassMetadata(*out_class, toplevel_class, TokenPosition::kNoSource, - class_offset - correction_offset_, 0); + class_offset - correction_offset_); } // We do not register expression evaluation classes with the VM: @@ -1640,8 +1607,7 @@ void KernelLoader::FinishClassLoading(const Class& klass, } if ((FLAG_enable_mirrors || has_pragma_annotation) && annotation_count > 0) { - library.AddFieldMetadata(field, TokenPosition::kNoSource, field_offset, - 0); + library.AddFieldMetadata(field, TokenPosition::kNoSource, field_offset); } fields_.Add(&field); } @@ -1740,7 +1706,7 @@ void KernelLoader::FinishClassLoading(const Class& klass, if ((FLAG_enable_mirrors || has_pragma_annotation) && annotation_count > 0) { library.AddFunctionMetadata(function, TokenPosition::kNoSource, - constructor_offset, 0); + constructor_offset); } } @@ -1779,7 +1745,6 @@ void KernelLoader::FinishClassLoading(const Class& klass, } void KernelLoader::FinishLoading(const Class& klass) { - ASSERT(!klass.is_declared_in_bytecode()); ASSERT(klass.IsTopLevel() || (klass.kernel_offset() > 0)); Zone* zone = Thread::Current()->zone(); @@ -2087,7 +2052,7 @@ void KernelLoader::LoadProcedure(const Library& library, if (annotation_count > 0) { library.AddFunctionMetadata(function, TokenPosition::kNoSource, - procedure_offset, 0); + procedure_offset); } if (has_pragma_annotation) { @@ -2410,11 +2375,9 @@ FunctionPtr CreateFieldInitializerFunction(Thread* thread, const PatchClass& initializer_owner = PatchClass::Handle(zone, PatchClass::New(field_owner, script)); const Library& lib = Library::Handle(zone, field_owner.library()); - if (!lib.is_declared_in_bytecode()) { - initializer_owner.set_library_kernel_data( - ExternalTypedData::Handle(zone, lib.kernel_data())); - initializer_owner.set_library_kernel_offset(lib.kernel_offset()); - } + initializer_owner.set_library_kernel_data( + ExternalTypedData::Handle(zone, lib.kernel_data())); + initializer_owner.set_library_kernel_offset(lib.kernel_offset()); // Create a static initializer. const Function& initializer_fun = Function::Handle( @@ -2441,7 +2404,7 @@ FunctionPtr CreateFieldInitializerFunction(Thread* thread, initializer_fun.set_token_pos(field.token_pos()); initializer_fun.set_end_token_pos(field.end_token_pos()); initializer_fun.set_accessor_field(field); - initializer_fun.InheritBinaryDeclarationFrom(field); + initializer_fun.InheritKernelOffsetFrom(field); initializer_fun.set_is_extension_member(field.is_extension_member()); field.SetInitializerFunction(initializer_fun); return initializer_fun.raw(); diff --git a/runtime/vm/kernel_loader.h b/runtime/vm/kernel_loader.h index 78268678564..11299565025 100644 --- a/runtime/vm/kernel_loader.h +++ b/runtime/vm/kernel_loader.h @@ -8,7 +8,6 @@ #if !defined(DART_PRECOMPILED_RUNTIME) #include "vm/bit_vector.h" -#include "vm/compiler/frontend/bytecode_reader.h" #include "vm/compiler/frontend/constant_reader.h" #include "vm/compiler/frontend/kernel_translation_helper.h" #include "vm/hash_map.h" @@ -410,7 +409,6 @@ class KernelLoader : public ValueObject { ConstantReader constant_reader_; TypeTranslator type_translator_; InferredTypeMetadataHelper inferred_type_metadata_helper_; - BytecodeMetadataHelper bytecode_metadata_helper_; Class& external_name_class_; Field& external_name_field_; diff --git a/runtime/vm/native_api_impl.cc b/runtime/vm/native_api_impl.cc index 388d6cb98d2..1c7c43a696b 100644 --- a/runtime/vm/native_api_impl.cc +++ b/runtime/vm/native_api_impl.cc @@ -207,26 +207,6 @@ DART_EXPORT Dart_Handle Dart_CompileAll() { #endif // defined(DART_PRECOMPILED_RUNTIME) } -DART_EXPORT Dart_Handle Dart_ReadAllBytecode() { -#if defined(DART_PRECOMPILED_RUNTIME) - return Api::NewError("%s: Cannot read bytecode on an AOT runtime.", - CURRENT_FUNC); -#else - DARTSCOPE(Thread::Current()); - API_TIMELINE_DURATION(T); - Dart_Handle result = Api::CheckAndFinalizePendingClasses(T); - if (Api::IsError(result)) { - return result; - } - CHECK_CALLBACK_STATE(T); - const Error& error = Error::Handle(T->zone(), Library::ReadAllBytecode()); - if (!error.IsNull()) { - return Api::NewHandle(T, error.raw()); - } - return Api::Success(); -#endif // defined(DART_PRECOMPILED_RUNTIME) -} - DART_EXPORT Dart_Handle Dart_FinalizeAllClasses() { #if defined(DART_PRECOMPILED_RUNTIME) return Api::NewError("%s: All classes are already finalized in AOT runtime.", diff --git a/runtime/vm/native_arguments.h b/runtime/vm/native_arguments.h index 18fdad652f3..b942e80dfaa 100644 --- a/runtime/vm/native_arguments.h +++ b/runtime/vm/native_arguments.h @@ -234,10 +234,9 @@ class NativeArguments { : public BitField {}; friend class Api; friend class NativeEntry; - friend class Interpreter; friend class Simulator; - // Allow simulator and interpreter to create NativeArguments in reverse order + // Allow simulator to create NativeArguments in reverse order // on the stack. NativeArguments(Thread* thread, int argc_tag, diff --git a/runtime/vm/native_entry.cc b/runtime/vm/native_entry.cc index 7a1311850ca..445ccf0ae64 100644 --- a/runtime/vm/native_entry.cc +++ b/runtime/vm/native_entry.cc @@ -273,16 +273,8 @@ void NativeEntry::LinkNativeCall(Dart_NativeArguments args) { StackFrameIterator::kNoCrossThreadIteration); StackFrame* caller_frame = iterator.NextFrame(); - Code& code = Code::Handle(zone); - Bytecode& bytecode = Bytecode::Handle(zone); - Function& func = Function::Handle(zone); - if (caller_frame->is_interpreted()) { - bytecode = caller_frame->LookupDartBytecode(); - func = bytecode.function(); - } else { - code = caller_frame->LookupDartCode(); - func = code.function(); - } + Code& code = Code::Handle(zone, caller_frame->LookupDartCode()); + Function& func = Function::Handle(zone, code.function()); if (FLAG_trace_natives) { THR_Print("Resolving native target for %s\n", func.ToCString()); @@ -295,63 +287,29 @@ void NativeEntry::LinkNativeCall(Dart_NativeArguments args) { #if defined(DEBUG) NativeFunction current_function = NULL; - if (caller_frame->is_interpreted()) { -#if !defined(DART_PRECOMPILED_RUNTIME) - ASSERT(FLAG_enable_interpreter); - NativeFunctionWrapper current_trampoline = KBCPatcher::GetNativeCallAt( - caller_frame->pc(), bytecode, ¤t_function); - ASSERT(current_function == - reinterpret_cast(LinkNativeCall)); - ASSERT(current_trampoline == &BootstrapNativeCallWrapper || - current_trampoline == &AutoScopeNativeCallWrapper || - current_trampoline == &NoScopeNativeCallWrapper); -#else - UNREACHABLE(); -#endif // !defined(DART_PRECOMPILED_RUNTIME) - } else { - const Code& current_trampoline = - Code::Handle(zone, CodePatcher::GetNativeCallAt( - caller_frame->pc(), code, ¤t_function)); - // Some other isolate(with code being shared in AOT) might have updated - // target function/trampoline already. - ASSERT(current_function == - reinterpret_cast(LinkNativeCall) || - current_function == target_function); - ASSERT(current_trampoline.raw() == - StubCode::CallBootstrapNative().raw() || - current_function == target_function); - } + const Code& current_trampoline = + Code::Handle(zone, CodePatcher::GetNativeCallAt( + caller_frame->pc(), code, ¤t_function)); + // Some other isolate(with code being shared in AOT) might have updated + // target function/trampoline already. + ASSERT(current_function == + reinterpret_cast(LinkNativeCall) || + current_function == target_function); + ASSERT(current_trampoline.raw() == StubCode::CallBootstrapNative().raw() || + current_function == target_function); #endif NativeFunction patch_target_function = target_function; - if (caller_frame->is_interpreted()) { -#if !defined(DART_PRECOMPILED_RUNTIME) - ASSERT(FLAG_enable_interpreter); - NativeFunctionWrapper trampoline; - if (is_bootstrap_native) { - trampoline = &BootstrapNativeCallWrapper; - } else if (is_auto_scope) { - trampoline = &AutoScopeNativeCallWrapper; - } else { - trampoline = &NoScopeNativeCallWrapper; - } - KBCPatcher::PatchNativeCallAt(caller_frame->pc(), bytecode, - patch_target_function, trampoline); -#else - UNREACHABLE(); -#endif // !defined(DART_PRECOMPILED_RUNTIME) + Code& trampoline = Code::Handle(zone); + if (is_bootstrap_native) { + trampoline = StubCode::CallBootstrapNative().raw(); + } else if (is_auto_scope) { + trampoline = StubCode::CallAutoScopeNative().raw(); } else { - Code& trampoline = Code::Handle(zone); - if (is_bootstrap_native) { - trampoline = StubCode::CallBootstrapNative().raw(); - } else if (is_auto_scope) { - trampoline = StubCode::CallAutoScopeNative().raw(); - } else { - trampoline = StubCode::CallNoScopeNative().raw(); - } - CodePatcher::PatchNativeCallAt(caller_frame->pc(), code, - patch_target_function, trampoline); + trampoline = StubCode::CallNoScopeNative().raw(); } + CodePatcher::PatchNativeCallAt(caller_frame->pc(), code, + patch_target_function, trampoline); if (FLAG_trace_natives) { THR_Print(" -> %p (%s)\n", target_function, diff --git a/runtime/vm/native_entry.h b/runtime/vm/native_entry.h index fae426144f8..2be609e4f49 100644 --- a/runtime/vm/native_entry.h +++ b/runtime/vm/native_entry.h @@ -171,7 +171,6 @@ class NativeEntryData : public ValueObject { const TypedData& data_; - friend class Interpreter; friend class ObjectPoolSerializationCluster; DISALLOW_COPY_AND_ASSIGN(NativeEntryData); }; diff --git a/runtime/vm/object.cc b/runtime/vm/object.cc index e20d3cfcb1b..e5af575c410 100644 --- a/runtime/vm/object.cc +++ b/runtime/vm/object.cc @@ -19,7 +19,6 @@ #include "vm/code_descriptors.h" #include "vm/code_observers.h" #include "vm/compiler/assembler/disassembler.h" -#include "vm/compiler/assembler/disassembler_kbc.h" #include "vm/compiler/jit/compiler.h" #include "vm/compiler/runtime_api.h" #include "vm/cpu.h" @@ -66,8 +65,6 @@ #include "vm/compiler/assembler/assembler.h" #include "vm/compiler/backend/code_statistics.h" #include "vm/compiler/compiler_state.h" -#include "vm/compiler/frontend/bytecode_fingerprints.h" -#include "vm/compiler/frontend/bytecode_reader.h" #include "vm/compiler/frontend/kernel_fingerprints.h" #include "vm/compiler/frontend/kernel_translation_helper.h" #include "vm/compiler/intrinsifier.h" @@ -156,7 +153,6 @@ ClassPtr Object::library_class_ = static_cast(RAW_NULL); ClassPtr Object::namespace_class_ = static_cast(RAW_NULL); ClassPtr Object::kernel_program_info_class_ = static_cast(RAW_NULL); ClassPtr Object::code_class_ = static_cast(RAW_NULL); -ClassPtr Object::bytecode_class_ = static_cast(RAW_NULL); ClassPtr Object::instructions_class_ = static_cast(RAW_NULL); ClassPtr Object::instructions_section_class_ = static_cast(RAW_NULL); ClassPtr Object::object_pool_class_ = static_cast(RAW_NULL); @@ -167,7 +163,6 @@ ClassPtr Object::var_descriptors_class_ = static_cast(RAW_NULL); ClassPtr Object::exception_handlers_class_ = static_cast(RAW_NULL); ClassPtr Object::context_class_ = static_cast(RAW_NULL); ClassPtr Object::context_scope_class_ = static_cast(RAW_NULL); -ClassPtr Object::dyncalltypecheck_class_ = static_cast(RAW_NULL); ClassPtr Object::singletargetcache_class_ = static_cast(RAW_NULL); ClassPtr Object::unlinkedcall_class_ = static_cast(RAW_NULL); ClassPtr Object::monomorphicsmiablecall_class_ = @@ -518,21 +513,6 @@ static type SpecialCharacter(type value) { return '\0'; } -static BytecodePtr CreateVMInternalBytecode(KernelBytecode::Opcode opcode) { - const KBCInstr* instructions = nullptr; - intptr_t instructions_size = 0; - - KernelBytecode::GetVMInternalBytecodeInstructions(opcode, &instructions, - &instructions_size); - - const auto& bytecode = Bytecode::Handle( - Bytecode::New(reinterpret_cast(instructions), instructions_size, - -1, Object::empty_object_pool())); - bytecode.set_pc_descriptors(Object::empty_descriptors()); - bytecode.set_exception_handlers(Object::empty_exception_handlers()); - return bytecode.raw(); -} - void Object::InitNullAndBool(Isolate* isolate) { // Should only be run by the vm isolate. ASSERT(isolate == Dart::vm_isolate()); @@ -839,9 +819,6 @@ void Object::Init(Isolate* isolate) { cls = Class::New(isolate); code_class_ = cls.raw(); - cls = Class::New(isolate); - bytecode_class_ = cls.raw(); - cls = Class::New(isolate); instructions_class_ = cls.raw(); @@ -872,9 +849,6 @@ void Object::Init(Isolate* isolate) { cls = Class::New(isolate); context_scope_class_ = cls.raw(); - cls = Class::New(isolate); - dyncalltypecheck_class_ = cls.raw(); - cls = Class::New(isolate); singletargetcache_class_ = cls.raw(); @@ -1159,30 +1133,6 @@ void Object::Init(Isolate* isolate) { // needs to be created earlier as VM isolate snapshot reader references it // before Object::FinalizeVMIsolate. - *implicit_getter_bytecode_ = - CreateVMInternalBytecode(KernelBytecode::kVMInternal_ImplicitGetter); - - *implicit_setter_bytecode_ = - CreateVMInternalBytecode(KernelBytecode::kVMInternal_ImplicitSetter); - - *implicit_static_getter_bytecode_ = CreateVMInternalBytecode( - KernelBytecode::kVMInternal_ImplicitStaticGetter); - - *method_extractor_bytecode_ = - CreateVMInternalBytecode(KernelBytecode::kVMInternal_MethodExtractor); - - *invoke_closure_bytecode_ = - CreateVMInternalBytecode(KernelBytecode::kVMInternal_InvokeClosure); - - *invoke_field_bytecode_ = - CreateVMInternalBytecode(KernelBytecode::kVMInternal_InvokeField); - - *nsm_dispatcher_bytecode_ = CreateVMInternalBytecode( - KernelBytecode::kVMInternal_NoSuchMethodDispatcher); - - *dynamic_invocation_forwarder_bytecode_ = CreateVMInternalBytecode( - KernelBytecode::kVMInternal_ForwardDynamicInvocation); - // Some thread fields need to be reinitialized as null constants have not been // initialized until now. Thread* thr = Thread::Current(); @@ -1251,22 +1201,6 @@ void Object::Init(Isolate* isolate) { ASSERT(extractor_parameter_types_->IsArray()); ASSERT(!extractor_parameter_names_->IsSmi()); ASSERT(extractor_parameter_names_->IsArray()); - ASSERT(!implicit_getter_bytecode_->IsSmi()); - ASSERT(implicit_getter_bytecode_->IsBytecode()); - ASSERT(!implicit_setter_bytecode_->IsSmi()); - ASSERT(implicit_setter_bytecode_->IsBytecode()); - ASSERT(!implicit_static_getter_bytecode_->IsSmi()); - ASSERT(implicit_static_getter_bytecode_->IsBytecode()); - ASSERT(!method_extractor_bytecode_->IsSmi()); - ASSERT(method_extractor_bytecode_->IsBytecode()); - ASSERT(!invoke_closure_bytecode_->IsSmi()); - ASSERT(invoke_closure_bytecode_->IsBytecode()); - ASSERT(!invoke_field_bytecode_->IsSmi()); - ASSERT(invoke_field_bytecode_->IsBytecode()); - ASSERT(!nsm_dispatcher_bytecode_->IsSmi()); - ASSERT(nsm_dispatcher_bytecode_->IsBytecode()); - ASSERT(!dynamic_invocation_forwarder_bytecode_->IsSmi()); - ASSERT(dynamic_invocation_forwarder_bytecode_->IsBytecode()); } void Object::FinishInit(Isolate* isolate) { @@ -1302,7 +1236,6 @@ void Object::Cleanup() { namespace_class_ = static_cast(RAW_NULL); kernel_program_info_class_ = static_cast(RAW_NULL); code_class_ = static_cast(RAW_NULL); - bytecode_class_ = static_cast(RAW_NULL); instructions_class_ = static_cast(RAW_NULL); instructions_section_class_ = static_cast(RAW_NULL); object_pool_class_ = static_cast(RAW_NULL); @@ -1313,7 +1246,6 @@ void Object::Cleanup() { exception_handlers_class_ = static_cast(RAW_NULL); context_class_ = static_cast(RAW_NULL); context_scope_class_ = static_cast(RAW_NULL); - dyncalltypecheck_class_ = static_cast(RAW_NULL); singletargetcache_class_ = static_cast(RAW_NULL); unlinkedcall_class_ = static_cast(RAW_NULL); monomorphicsmiablecall_class_ = static_cast(RAW_NULL); @@ -1405,7 +1337,6 @@ void Object::FinalizeVMIsolate(Isolate* isolate) { SET_CLASS_NAME(namespace, Namespace); SET_CLASS_NAME(kernel_program_info, KernelProgramInfo); SET_CLASS_NAME(code, Code); - SET_CLASS_NAME(bytecode, Bytecode); SET_CLASS_NAME(instructions, Instructions); SET_CLASS_NAME(instructions_section, InstructionsSection); SET_CLASS_NAME(object_pool, ObjectPool); @@ -1416,7 +1347,6 @@ void Object::FinalizeVMIsolate(Isolate* isolate) { SET_CLASS_NAME(exception_handlers, ExceptionHandlers); SET_CLASS_NAME(context, Context); SET_CLASS_NAME(context_scope, ContextScope); - SET_CLASS_NAME(dyncalltypecheck, ParameterTypeCheck); SET_CLASS_NAME(singletargetcache, SingleTargetCache); SET_CLASS_NAME(unlinkedcall, UnlinkedCall); SET_CLASS_NAME(monomorphicsmiablecall, MonomorphicSmiableCall); @@ -2887,8 +2817,7 @@ ClassPtr Class::New(Isolate* isolate, bool register_class) { // references, but do not recompute size. result.set_is_prefinalized(); } - NOT_IN_PRECOMPILED(result.set_is_declared_in_bytecode(false)); - NOT_IN_PRECOMPILED(result.set_binary_declaration_offset(0)); + NOT_IN_PRECOMPILED(result.set_kernel_offset(0)); result.InitEmptyFields(); if (register_class) { isolate->class_table()->Register(result); @@ -3165,7 +3094,7 @@ void Class::set_library(const Library& value) const { void Class::set_type_parameters(const TypeArguments& value) const { ASSERT((num_type_arguments() == kUnknownNumTypeArguments) || - is_declared_in_bytecode() || is_prefinalized()); + is_prefinalized()); StorePointer(&raw_ptr()->type_parameters_, value.raw()); } @@ -3673,7 +3602,7 @@ FunctionPtr Function::CreateMethodExtractor(const String& getter_name) const { extractor.set_parameter_names(Object::extractor_parameter_names()); extractor.set_result_type(Object::dynamic_type()); - extractor.InheritBinaryDeclarationFrom(*this); + extractor.InheritKernelOffsetFrom(*this); extractor.set_extracted_method_closure(closure_function); extractor.set_is_debuggable(false); @@ -3814,7 +3743,6 @@ FunctionPtr Function::CreateDynamicInvocationForwarder( forwarder.set_is_visible(false); forwarder.ClearICDataArray(); - forwarder.ClearBytecode(); forwarder.ClearCode(); forwarder.set_usage_counter(0); forwarder.set_deoptimization_counter(0); @@ -3822,7 +3750,7 @@ FunctionPtr Function::CreateDynamicInvocationForwarder( forwarder.set_inlining_depth(0); forwarder.set_optimized_call_site_count(0); - forwarder.InheritBinaryDeclarationFrom(*this); + forwarder.InheritKernelOffsetFrom(*this); const Array& checks = Array::Handle(zone, Array::New(1)); checks.SetAt(0, *this); @@ -4350,14 +4278,7 @@ void Class::EnsureDeclarationLoaded() const { #if defined(DART_PRECOMPILED_RUNTIME) UNREACHABLE(); #else - // Loading of class declaration can be postponed until needed - // if class comes from bytecode. - if (!is_declared_in_bytecode()) { - FATAL1("Unable to use class %s which is not loaded yet.", ToCString()); - } - kernel::BytecodeReader::LoadClassDeclaration(*this); - ASSERT(is_declaration_loaded()); - ASSERT(is_type_finalized()); + FATAL1("Unable to use class %s which is not loaded yet.", ToCString()); #endif } } @@ -4548,8 +4469,7 @@ ClassPtr Class::NewCommon(intptr_t index) { result.set_num_type_arguments(kUnknownNumTypeArguments); result.set_num_native_fields(0); result.set_state_bits(0); - NOT_IN_PRECOMPILED(result.set_is_declared_in_bytecode(false)); - NOT_IN_PRECOMPILED(result.set_binary_declaration_offset(0)); + NOT_IN_PRECOMPILED(result.set_kernel_offset(0)); result.InitEmptyFields(); return result.raw(); } @@ -4862,8 +4782,6 @@ const char* Class::GenerateUserVisibleName() const { return Symbols::KernelProgramInfo().ToCString(); case kCodeCid: return Symbols::Code().ToCString(); - case kBytecodeCid: - return Symbols::Bytecode().ToCString(); case kInstructionsCid: return Symbols::Instructions().ToCString(); case kInstructionsSectionCid: @@ -4884,8 +4802,6 @@ const char* Class::GenerateUserVisibleName() const { return Symbols::Context().ToCString(); case kContextScopeCid: return Symbols::ContextScope().ToCString(); - case kParameterTypeCheckCid: - return Symbols::ParameterTypeCheck().ToCString(); case kSingleTargetCacheCid: return Symbols::SingleTargetCache().ToCString(); case kICDataCid: @@ -4946,9 +4862,6 @@ void Class::set_end_token_pos(TokenPosition token_pos) const { int32_t Class::SourceFingerprint() const { #if !defined(DART_PRECOMPILED_RUNTIME) - if (is_declared_in_bytecode()) { - return 0; // TODO(37353): Implement or remove. - } return kernel::KernelSourceFingerprintHelper::CalculateClassFingerprint( *this); #else @@ -6799,76 +6712,13 @@ void Function::AttachCode(const Code& value) const { bool Function::HasCode() const { NoSafepointScope no_safepoint; ASSERT(raw_ptr()->code_ != Code::null()); -#if defined(DART_PRECOMPILED_RUNTIME) return raw_ptr()->code_ != StubCode::LazyCompile().raw(); -#else - return raw_ptr()->code_ != StubCode::LazyCompile().raw() && - raw_ptr()->code_ != StubCode::InterpretCall().raw(); -#endif // defined(DART_PRECOMPILED_RUNTIME) } -#if !defined(DART_PRECOMPILED_RUNTIME) -bool Function::IsBytecodeAllowed(Zone* zone) const { - if (FLAG_intrinsify) { - // Bigint intrinsics should not be interpreted, because their Dart version - // is only to be used when intrinsics are disabled. Mixing an interpreted - // Dart version with a compiled intrinsified version results in a mismatch - // in the number of digits processed by each call. - switch (recognized_kind()) { - case MethodRecognizer::kBigint_lsh: - case MethodRecognizer::kBigint_rsh: - case MethodRecognizer::kBigint_absAdd: - case MethodRecognizer::kBigint_absSub: - case MethodRecognizer::kBigint_mulAdd: - case MethodRecognizer::kBigint_sqrAdd: - case MethodRecognizer::kBigint_estimateQuotientDigit: - case MethodRecognizer::kMontgomery_mulMod: - return false; - default: - break; - } - } - switch (kind()) { - case FunctionLayout::kDynamicInvocationForwarder: - return is_declared_in_bytecode(); - case FunctionLayout::kImplicitClosureFunction: - case FunctionLayout::kIrregexpFunction: - case FunctionLayout::kFfiTrampoline: - return false; - default: - return true; - } -} - -void Function::AttachBytecode(const Bytecode& value) const { - DEBUG_ASSERT(IsMutatorOrAtSafepoint()); - ASSERT(!value.IsNull()); - // Finish setting up code before activating it. - if (!value.InVMIsolateHeap()) { - value.set_function(*this); - } - StorePointer(&raw_ptr()->bytecode_, value.raw()); - - // We should not have loaded the bytecode if the function had code. - // However, we may load the bytecode to access source positions (see - // ProcessBytecodeTokenPositionsEntry in kernel.cc). - // In that case, do not install InterpretCall stub below. - if (FLAG_enable_interpreter && !HasCode()) { - // Set the code entry_point to InterpretCall stub. - SetInstructions(StubCode::InterpretCall()); - } -} -#endif // !defined(DART_PRECOMPILED_RUNTIME) - bool Function::HasCode(FunctionPtr function) { NoSafepointScope no_safepoint; ASSERT(function->ptr()->code_ != Code::null()); -#if defined(DART_PRECOMPILED_RUNTIME) return function->ptr()->code_ != StubCode::LazyCompile().raw(); -#else - return function->ptr()->code_ != StubCode::LazyCompile().raw() && - function->ptr()->code_ != StubCode::InterpretCall().raw(); -#endif // !defined(DART_PRECOMPILED_RUNTIME) } void Function::ClearCode() const { @@ -6879,19 +6729,7 @@ void Function::ClearCode() const { StorePointer(&raw_ptr()->unoptimized_code_, Code::null()); - if (FLAG_enable_interpreter && HasBytecode()) { - SetInstructions(StubCode::InterpretCall()); - } else { - SetInstructions(StubCode::LazyCompile()); - } -#endif // defined(DART_PRECOMPILED_RUNTIME) -} - -void Function::ClearBytecode() const { -#if defined(DART_PRECOMPILED_RUNTIME) - UNREACHABLE(); -#else - StorePointer(&raw_ptr()->bytecode_, Bytecode::null()); + SetInstructions(StubCode::LazyCompile()); #endif // defined(DART_PRECOMPILED_RUNTIME) } @@ -6952,14 +6790,9 @@ void Function::SwitchToLazyCompiledUnoptimizedCode() const { const Code& unopt_code = Code::Handle(zone, unoptimized_code()); if (unopt_code.IsNull()) { - // Set the lazy compile or interpreter call stub code. - if (FLAG_enable_interpreter && HasBytecode()) { - TIR_Print("Switched to interpreter call stub for %s\n", ToCString()); - SetInstructions(StubCode::InterpretCall()); - } else { - TIR_Print("Switched to lazy compile stub for %s\n", ToCString()); - SetInstructions(StubCode::LazyCompile()); - } + // Set the lazy compile stub code. + TIR_Print("Switched to lazy compile stub for %s\n", ToCString()); + SetInstructions(StubCode::LazyCompile()); return; } @@ -7549,7 +7382,6 @@ void Function::SetForwardingChecks(const Array& checks) const { // ffi trampoline function: FfiTrampolineData (Dart->C) // dyn inv forwarder: Array[0] = Function target // Array[1] = TypeArguments default type args -// Array[i] = ParameterTypeCheck void Function::set_data(const Object& value) const { StorePointer(&raw_ptr()->data_, value.raw()); } @@ -8839,8 +8671,7 @@ FunctionPtr Function::New(const String& name, NOT_IN_PRECOMPILED(result.set_optimized_instruction_count(0)); NOT_IN_PRECOMPILED(result.set_optimized_call_site_count(0)); NOT_IN_PRECOMPILED(result.set_inlining_depth(0)); - NOT_IN_PRECOMPILED(result.set_is_declared_in_bytecode(false)); - NOT_IN_PRECOMPILED(result.set_binary_declaration_offset(0)); + NOT_IN_PRECOMPILED(result.set_kernel_offset(0)); result.set_is_optimizable(is_native ? false : true); result.set_is_background_optimizable(is_native ? false : true); result.set_is_inlinable(true); @@ -9047,7 +8878,7 @@ FunctionPtr Function::ImplicitClosureFunction() const { } } closure_function.TruncateUnusedParameterFlags(); - closure_function.InheritBinaryDeclarationFrom(*this); + closure_function.InheritKernelOffsetFrom(*this); // Change covariant parameter types to either Object? for an opted-in implicit // closure or to Object* for a legacy implicit closure. @@ -9329,25 +9160,19 @@ ClassPtr Function::origin() const { return PatchClass::Cast(obj).origin_class(); } -void Function::InheritBinaryDeclarationFrom(const Function& src) const { +void Function::InheritKernelOffsetFrom(const Function& src) const { #if defined(DART_PRECOMPILED_RUNTIME) UNREACHABLE(); #else - StoreNonPointer(&raw_ptr()->binary_declaration_, - src.raw_ptr()->binary_declaration_); + StoreNonPointer(&raw_ptr()->kernel_offset_, src.raw_ptr()->kernel_offset_); #endif } -void Function::InheritBinaryDeclarationFrom(const Field& src) const { +void Function::InheritKernelOffsetFrom(const Field& src) const { #if defined(DART_PRECOMPILED_RUNTIME) UNREACHABLE(); #else - if (src.is_declared_in_bytecode()) { - set_is_declared_in_bytecode(true); - set_bytecode_offset(src.bytecode_offset()); - } else { - set_kernel_offset(src.kernel_offset()); - } + set_kernel_offset(src.kernel_offset()); #endif } @@ -9426,7 +9251,6 @@ ExternalTypedDataPtr Function::KernelData() const { } intptr_t Function::KernelDataProgramOffset() const { - ASSERT(!is_declared_in_bytecode()); if (IsNoSuchMethodDispatcher() || IsInvokeFieldDispatcher() || IsFfiTrampoline()) { return 0; @@ -9447,7 +9271,6 @@ intptr_t Function::KernelDataProgramOffset() const { const Object& obj = Object::Handle(raw_ptr()->owner_); if (obj.IsClass()) { Library& lib = Library::Handle(Class::Cast(obj).library()); - ASSERT(!lib.is_declared_in_bytecode()); return lib.kernel_offset(); } ASSERT(obj.IsPatchClass()); @@ -9458,12 +9281,6 @@ bool Function::HasOptimizedCode() const { return HasCode() && Code::Handle(CurrentCode()).is_optimized(); } -bool Function::ShouldCompilerOptimize() const { - return !FLAG_enable_interpreter || - ((unoptimized_code() != Object::null()) && WasCompiled()) || - ForceOptimize(); -} - const char* Function::NameCString(NameVisibility name_visibility) const { switch (name_visibility) { case kInternalName: @@ -9665,10 +9482,6 @@ StringPtr Function::GetSource() const { // arguments. int32_t Function::SourceFingerprint() const { #if !defined(DART_PRECOMPILED_RUNTIME) - if (is_declared_in_bytecode()) { - return kernel::BytecodeFingerprintHelper::CalculateFunctionFingerprint( - *this); - } return kernel::KernelSourceFingerprintHelper::CalculateFunctionFingerprint( *this); #else @@ -9793,12 +9606,6 @@ bool Function::CheckSourceFingerprint(int32_t fp) const { return true; // The kernel structure has been altered, skip checking. } - if (is_declared_in_bytecode()) { - // AST and bytecode compute different fingerprints, and we only track one - // fingerprint set. - return true; - } - if (SourceFingerprint() != fp) { // This output can be copied into a file, then used with sed // to replace the old values. @@ -10310,17 +10117,15 @@ ExternalTypedDataPtr Field::KernelData() const { return PatchClass::Cast(obj).library_kernel_data(); } -void Field::InheritBinaryDeclarationFrom(const Field& src) const { +void Field::InheritKernelOffsetFrom(const Field& src) const { #if defined(DART_PRECOMPILED_RUNTIME) UNREACHABLE(); #else - StoreNonPointer(&raw_ptr()->binary_declaration_, - src.raw_ptr()->binary_declaration_); + StoreNonPointer(&raw_ptr()->kernel_offset_, src.raw_ptr()->kernel_offset_); #endif } intptr_t Field::KernelDataProgramOffset() const { - ASSERT(!is_declared_in_bytecode()); const Object& obj = Object::Handle(raw_ptr()->owner_); // During background JIT compilation field objects are copied // and copy points to the original field via the owner field. @@ -10328,7 +10133,6 @@ intptr_t Field::KernelDataProgramOffset() const { return Field::Cast(obj).KernelDataProgramOffset(); } else if (obj.IsClass()) { Library& lib = Library::Handle(Class::Cast(obj).library()); - ASSERT(!lib.is_declared_in_bytecode()); return lib.kernel_offset(); } ASSERT(obj.IsPatchClass()); @@ -10385,8 +10189,7 @@ void Field::InitializeNew(const Field& result, result.set_is_unboxing_candidate(!is_final && !is_late && !is_static); } result.set_initializer_changed_after_initialization(false); - NOT_IN_PRECOMPILED(result.set_is_declared_in_bytecode(false)); - NOT_IN_PRECOMPILED(result.set_binary_declaration_offset(0)); + NOT_IN_PRECOMPILED(result.set_kernel_offset(0)); result.set_has_pragma(false); result.set_static_type_exactness_state( StaticTypeExactnessState::NotTracking()); @@ -10458,15 +10261,12 @@ FieldPtr Field::Clone(const Field& original) const { Field& clone = Field::Handle(); clone ^= Object::Clone(*this, Heap::kOld); clone.SetOriginal(original); - clone.InheritBinaryDeclarationFrom(original); + clone.InheritKernelOffsetFrom(original); return clone.raw(); } int32_t Field::SourceFingerprint() const { #if !defined(DART_PRECOMPILED_RUNTIME) - if (is_declared_in_bytecode()) { - return 0; // TODO(37353): Implement or remove. - } return kernel::KernelSourceFingerprintHelper::CalculateFieldFingerprint( *this); #else @@ -11362,7 +11162,6 @@ GrowableObjectArrayPtr Script::GenerateLineNumberArray() const { LookupSourceAndLineStarts(zone); if (line_starts() == TypedData::null()) { // Scripts in the AOT snapshot do not have a line starts array. - // Neither do some scripts coming from bytecode. // A well-formed line number array has a leading null. info.Add(line_separator); // New line. return info.raw(); @@ -11483,8 +11282,7 @@ bool Script::GetTokenLocationUsingLineStarts(TokenPosition target_token_pos, Zone* zone = Thread::Current()->zone(); TypedData& line_starts_data = TypedData::Handle(zone, line_starts()); - // Scripts loaded from bytecode may have null line_starts(). - if (line_starts_data.IsNull()) return false; + ASSERT(!line_starts_data.IsNull()); kernel::KernelLineStartsReader line_starts_reader(line_starts_data, zone); line_starts_reader.LocationForPosition(target_token_pos.value(), line, @@ -11524,7 +11322,6 @@ void Script::GetTokenLocation(TokenPosition token_pos, LookupSourceAndLineStarts(zone); if (line_starts() == TypedData::null()) { // Scripts in the AOT snapshot do not have a line starts array. - // Neither do some scripts coming from bytecode. *line = -1; if (column != NULL) { *column = -1; @@ -11567,7 +11364,6 @@ void Script::TokenRangeAtLine(intptr_t line_number, LookupSourceAndLineStarts(zone); if (line_starts() == TypedData::null()) { // Scripts in the AOT snapshot do not have a line starts array. - // Neither do some scripts coming from bytecode. *first_token_index = TokenPosition::kNoSource; *last_token_index = TokenPosition::kNoSource; return; @@ -11914,8 +11710,7 @@ static StringPtr MakeTypeParameterMetaName(Thread* thread, void Library::AddMetadata(const Object& owner, const String& name, TokenPosition token_pos, - intptr_t kernel_offset, - intptr_t bytecode_offset) const { + intptr_t kernel_offset) const { #if defined(DART_PRECOMPILED_RUNTIME) UNREACHABLE(); #else @@ -11932,12 +11727,7 @@ void Library::AddMetadata(const Object& owner, field.SetFieldType(Object::dynamic_type()); field.set_is_reflectable(false); field.SetStaticValue(Array::empty_array(), true); - if (bytecode_offset > 0) { - field.set_is_declared_in_bytecode(true); - field.set_bytecode_offset(bytecode_offset); - } else { - field.set_kernel_offset(kernel_offset); - } + field.set_kernel_offset(kernel_offset); GrowableObjectArray& metadata = GrowableObjectArray::Handle(zone, this->metadata()); metadata.Add(field, Heap::kOld); @@ -11947,39 +11737,36 @@ void Library::AddMetadata(const Object& owner, void Library::AddClassMetadata(const Class& cls, const Object& tl_owner, TokenPosition token_pos, - intptr_t kernel_offset, - intptr_t bytecode_offset) const { + intptr_t kernel_offset) const { Thread* thread = Thread::Current(); Zone* zone = thread->zone(); // We use the toplevel class as the owner of a class's metadata field because // a class's metadata is in scope of the library, not the class. AddMetadata(tl_owner, String::Handle(zone, MakeClassMetaName(thread, zone, cls)), - token_pos, kernel_offset, bytecode_offset); + token_pos, kernel_offset); } void Library::AddFieldMetadata(const Field& field, TokenPosition token_pos, - intptr_t kernel_offset, - intptr_t bytecode_offset) const { + intptr_t kernel_offset) const { Thread* thread = Thread::Current(); Zone* zone = thread->zone(); const auto& owner = Object::Handle(zone, field.RawOwner()); const auto& name = String::Handle(zone, MakeFieldMetaName(thread, zone, field)); - AddMetadata(owner, name, token_pos, kernel_offset, bytecode_offset); + AddMetadata(owner, name, token_pos, kernel_offset); } void Library::AddFunctionMetadata(const Function& func, TokenPosition token_pos, - intptr_t kernel_offset, - intptr_t bytecode_offset) const { + intptr_t kernel_offset) const { Thread* thread = Thread::Current(); Zone* zone = thread->zone(); const auto& owner = Object::Handle(zone, func.RawOwner()); const auto& name = String::Handle(zone, MakeFunctionMetaName(thread, zone, func)); - AddMetadata(owner, name, token_pos, kernel_offset, bytecode_offset); + AddMetadata(owner, name, token_pos, kernel_offset); } void Library::AddTypeParameterMetadata(const TypeParameter& param, @@ -11989,15 +11776,13 @@ void Library::AddTypeParameterMetadata(const TypeParameter& param, const auto& owner = Class::Handle(zone, param.parameterized_class()); const auto& name = String::Handle(zone, MakeTypeParameterMetaName(thread, zone, param)); - AddMetadata(owner, name, token_pos, 0, 0); + AddMetadata(owner, name, token_pos, 0); } void Library::AddLibraryMetadata(const Object& tl_owner, TokenPosition token_pos, - intptr_t kernel_offset, - intptr_t bytecode_offset) const { - AddMetadata(tl_owner, Symbols::TopLevel(), token_pos, kernel_offset, - bytecode_offset); + intptr_t kernel_offset) const { + AddMetadata(tl_owner, Symbols::TopLevel(), token_pos, kernel_offset); } StringPtr Library::MakeMetadataName(const Object& obj) const { @@ -12041,13 +11826,8 @@ void Library::CloneMetadataFrom(const Library& from_library, const Field& from_field = Field::Handle(from_library.GetMetadataField(metaname)); if (!from_field.IsNull()) { - if (from_field.is_declared_in_bytecode()) { - AddFunctionMetadata(to_fun, from_field.token_pos(), 0, - from_field.bytecode_offset()); - } else { - AddFunctionMetadata(to_fun, from_field.token_pos(), - from_field.kernel_offset(), 0); - } + AddFunctionMetadata(to_fun, from_field.token_pos(), + from_field.kernel_offset()); } } @@ -12075,13 +11855,9 @@ ObjectPtr Library::GetMetadata(const Object& obj) const { } Object& metadata = Object::Handle(field.StaticValue()); if (metadata.raw() == Object::empty_array().raw()) { - if (field.is_declared_in_bytecode()) { - metadata = kernel::BytecodeReader::ReadAnnotation(field); - } else { - ASSERT(field.kernel_offset() > 0); - metadata = kernel::EvaluateMetadata( - field, /* is_annotations_offset = */ obj.IsLibrary()); - } + ASSERT(field.kernel_offset() > 0); + metadata = kernel::EvaluateMetadata( + field, /* is_annotations_offset = */ obj.IsLibrary()); if (metadata.IsArray() || metadata.IsNull()) { ASSERT(metadata.raw() != Object::empty_array().raw()); if (!Compiler::IsBackgroundCompilation()) { @@ -12099,22 +11875,6 @@ ObjectPtr Library::GetMetadata(const Object& obj) const { #endif // defined(DART_PRECOMPILED_RUNTIME) } -ArrayPtr Library::GetExtendedMetadata(const Object& obj, intptr_t count) const { -#if defined(DART_PRECOMPILED_RUNTIME) - return Object::empty_array().raw(); -#else - RELEASE_ASSERT(obj.IsFunction() || obj.IsLibrary()); - const String& metaname = String::Handle(MakeMetadataName(obj)); - Field& field = Field::Handle(GetMetadataField(metaname)); - if (field.IsNull()) { - // There is no metadata for this object. - return Object::empty_array().raw(); - } - ASSERT(field.is_declared_in_bytecode()); - return kernel::BytecodeReader::ReadExtendedAnnotations(field, count); -#endif // defined(DART_PRECOMPILED_RUNTIME) -} - static bool ShouldBePrivate(const String& name) { return (name.Length() >= 1 && name.CharAt(0) == '_') || (name.Length() >= 5 && @@ -12966,8 +12726,7 @@ LibraryPtr Library::NewLibraryHelper(const String& url, bool import_core_lib) { result.set_debuggable(true); } result.set_is_dart_scheme(dart_scheme); - NOT_IN_PRECOMPILED(result.set_is_declared_in_bytecode(false)); - NOT_IN_PRECOMPILED(result.set_binary_declaration_offset(0)); + NOT_IN_PRECOMPILED(result.set_kernel_offset(0)); result.StoreNonPointer(&result.raw_ptr()->load_state_, LibraryLayout::kAllocated); result.StoreNonPointer(&result.raw_ptr()->index_, -1); @@ -13353,18 +13112,6 @@ static ObjectPtr EvaluateCompiledExpressionHelper( result = DartEntry::InvokeFunction(callee, real_arguments, args_desc); } - if (callee.is_declared_in_bytecode()) { - // Expression evaluation binary expires immediately after evaluation is - // finished. However, hot reload may still find corresponding - // KernelProgramInfo object in the heap and it would try to patch it. - // To prevent accessing stale kernel binary in ResetObjectTable, bytecode - // component of the callee's KernelProgramInfo is reset here. - const auto& script = Script::Handle(zone, callee.script()); - const auto& info = - KernelProgramInfo::Handle(zone, script.kernel_program_info()); - info.set_bytecode_component(Object::null_array()); - } - return result.raw(); #endif } @@ -14044,11 +13791,6 @@ ClassPtr KernelProgramInfo::InsertClass(Thread* thread, return result.raw(); } -void KernelProgramInfo::set_bytecode_component( - const Array& bytecode_component) const { - StorePointer(&raw_ptr()->bytecode_component_, bytecode_component.raw()); -} - ErrorPtr Library::CompileAll(bool ignore_error /* = false */) { Thread* thread = Thread::Current(); Zone* zone = thread->zone(); @@ -14129,33 +13871,6 @@ ErrorPtr Library::FinalizeAllClasses() { return Error::null(); } -ErrorPtr Library::ReadAllBytecode() { - Thread* thread = Thread::Current(); - ASSERT(thread->IsMutatorThread()); - Zone* zone = thread->zone(); - Error& error = Error::Handle(zone); - const GrowableObjectArray& libs = GrowableObjectArray::Handle( - Isolate::Current()->object_store()->libraries()); - Library& lib = Library::Handle(zone); - Class& cls = Class::Handle(zone); - for (int i = 0; i < libs.Length(); i++) { - lib ^= libs.At(i); - ClassDictionaryIterator it(lib, ClassDictionaryIterator::kIteratePrivate); - while (it.HasNext()) { - cls = it.GetNextClass(); - error = cls.EnsureIsFinalized(thread); - if (!error.IsNull()) { - return error.raw(); - } - error = Compiler::ReadAllBytecode(cls); - if (!error.IsNull()) { - return error.raw(); - } - } - } - - return Error::null(); -} #endif // !defined(DART_PRECOMPILED_RUNTIME) // Return Function::null() if function does not exist in libs. @@ -14416,8 +14131,7 @@ void ObjectPool::DebugPrint() const { for (intptr_t i = 0; i < Length(); i++) { intptr_t offset = OffsetFromIndex(i); THR_Print(" [pp+0x%" Px "] ", offset); - if ((TypeAt(i) == EntryType::kTaggedObject) || - (TypeAt(i) == EntryType::kNativeEntryData)) { + if (TypeAt(i) == EntryType::kTaggedObject) { const Object& obj = Object::Handle(ObjectAt(i)); THR_Print("%s (obj)\n", obj.ToCString()); } else if (TypeAt(i) == EntryType::kNativeFunction) { @@ -15135,43 +14849,6 @@ const char* ExceptionHandlers::ToCString() const { #undef FORMAT2 } -void ParameterTypeCheck::set_type_or_bound(const AbstractType& value) const { - StorePointer(&raw_ptr()->type_or_bound_, value.raw()); -} - -void ParameterTypeCheck::set_param(const AbstractType& value) const { - StorePointer(&raw_ptr()->param_, value.raw()); -} - -void ParameterTypeCheck::set_name(const String& value) const { - StorePointer(&raw_ptr()->name_, value.raw()); -} - -void ParameterTypeCheck::set_cache(const SubtypeTestCache& value) const { - StorePointer(&raw_ptr()->cache_, value.raw()); -} - -const char* ParameterTypeCheck::ToCString() const { - Zone* zone = Thread::Current()->zone(); - return zone->PrintToString("ParameterTypeCheck(%" Pd " %s %s %s)", index(), - Object::Handle(zone, param()).ToCString(), - Object::Handle(zone, type_or_bound()).ToCString(), - Object::Handle(zone, name()).ToCString()); -} - -ParameterTypeCheckPtr ParameterTypeCheck::New() { - ParameterTypeCheck& result = ParameterTypeCheck::Handle(); - { - ObjectPtr raw = - Object::Allocate(ParameterTypeCheck::kClassId, - ParameterTypeCheck::InstanceSize(), Heap::kOld); - NoSafepointScope no_safepoint; - result ^= raw; - } - result.set_index(0); - return result.raw(); -} - void SingleTargetCache::set_target(const Code& value) const { StorePointer(&raw_ptr()->target_, value.raw()); } @@ -17265,235 +16942,6 @@ void Code::DumpSourcePositions(bool relative_addresses) const { reader.DumpSourcePositions(relative_addresses ? 0 : PayloadStart()); } -void Bytecode::Disassemble(DisassemblyFormatter* formatter) const { -#if !defined(PRODUCT) || defined(FORCE_INCLUDE_DISASSEMBLER) -#if !defined(DART_PRECOMPILED_RUNTIME) - if (!FLAG_support_disassembler) { - return; - } - uword start = PayloadStart(); - intptr_t size = Size(); - if (formatter == NULL) { - KernelBytecodeDisassembler::Disassemble(start, start + size, *this); - } else { - KernelBytecodeDisassembler::Disassemble(start, start + size, formatter, - *this); - } -#endif // !defined(DART_PRECOMPILED_RUNTIME) -#endif // !defined(PRODUCT) || defined(FORCE_INCLUDE_DISASSEMBLER) -} - -BytecodePtr Bytecode::New(uword instructions, - intptr_t instructions_size, - intptr_t instructions_offset, - const ObjectPool& object_pool) { - ASSERT(Object::bytecode_class() != Class::null()); - Bytecode& result = Bytecode::Handle(); - { - uword size = Bytecode::InstanceSize(); - ObjectPtr raw = Object::Allocate(Bytecode::kClassId, size, Heap::kOld); - NoSafepointScope no_safepoint; - result ^= raw; - result.set_instructions(instructions); - result.set_instructions_size(instructions_size); - result.set_object_pool(object_pool); - result.set_pc_descriptors(Object::empty_descriptors()); - result.set_instructions_binary_offset(instructions_offset); - result.set_source_positions_binary_offset(0); - result.set_local_variables_binary_offset(0); - } - return result.raw(); -} - -ExternalTypedDataPtr Bytecode::GetBinary(Zone* zone) const { - const Function& func = Function::Handle(zone, function()); - if (func.IsNull()) { - return ExternalTypedData::null(); - } - const Script& script = Script::Handle(zone, func.script()); - const KernelProgramInfo& info = - KernelProgramInfo::Handle(zone, script.kernel_program_info()); - return info.metadata_payloads(); -} - -TokenPosition Bytecode::GetTokenIndexOfPC(uword return_address) const { -#if defined(DART_PRECOMPILED_RUNTIME) - UNREACHABLE(); -#else - if (!HasSourcePositions()) { - return TokenPosition::kNoSource; - } - uword pc_offset = return_address - PayloadStart(); - // pc_offset could equal to bytecode size if the last instruction is Throw. - ASSERT(pc_offset <= static_cast(Size())); - kernel::BytecodeSourcePositionsIterator iter(Thread::Current()->zone(), - *this); - TokenPosition token_pos = TokenPosition::kNoSource; - while (iter.MoveNext()) { - if (pc_offset <= iter.PcOffset()) { - break; - } - token_pos = iter.TokenPos(); - } - return token_pos; -#endif -} - -intptr_t Bytecode::GetTryIndexAtPc(uword return_address) const { -#if defined(DART_PRECOMPILED_RUNTIME) - UNREACHABLE(); -#else - intptr_t try_index = -1; - const uword pc_offset = return_address - PayloadStart(); - const PcDescriptors& descriptors = PcDescriptors::Handle(pc_descriptors()); - PcDescriptors::Iterator iter(descriptors, PcDescriptorsLayout::kAnyKind); - while (iter.MoveNext()) { - // PC descriptors for try blocks in bytecode are generated in pairs, - // marking start and end of a try block. - // See BytecodeReaderHelper::ReadExceptionsTable for details. - const intptr_t current_try_index = iter.TryIndex(); - const uword start_pc = iter.PcOffset(); - if (pc_offset < start_pc) { - break; - } - const bool has_next = iter.MoveNext(); - ASSERT(has_next); - const uword end_pc = iter.PcOffset(); - if (start_pc <= pc_offset && pc_offset < end_pc) { - ASSERT(try_index < current_try_index); - try_index = current_try_index; - } - } - return try_index; -#endif -} - -uword Bytecode::GetFirstDebugCheckOpcodePc() const { -#if defined(DART_PRECOMPILED_RUNTIME) - UNREACHABLE(); -#else - uword pc = PayloadStart(); - const uword end_pc = pc + Size(); - while (pc < end_pc) { - if (KernelBytecode::IsDebugCheckOpcode( - reinterpret_cast(pc))) { - return pc; - } - pc = KernelBytecode::Next(pc); - } - return 0; -#endif -} - -uword Bytecode::GetDebugCheckedOpcodeReturnAddress(uword from_offset, - uword to_offset) const { -#if defined(DART_PRECOMPILED_RUNTIME) - UNREACHABLE(); -#else - uword pc = PayloadStart() + from_offset; - const uword end_pc = pc + (to_offset - from_offset); - while (pc < end_pc) { - uword next_pc = KernelBytecode::Next(pc); - if (KernelBytecode::IsDebugCheckedOpcode( - reinterpret_cast(pc))) { - // Return the pc after the opcode, i.e. its 'return address'. - return next_pc; - } - pc = next_pc; - } - return 0; -#endif -} - -const char* Bytecode::ToCString() const { - return Thread::Current()->zone()->PrintToString("Bytecode(%s)", - QualifiedName()); -} - -static const char* BytecodeStubName(const Bytecode& bytecode) { - if (bytecode.raw() == Object::implicit_getter_bytecode().raw()) { - return "[Bytecode Stub] VMInternal_ImplicitGetter"; - } else if (bytecode.raw() == Object::implicit_setter_bytecode().raw()) { - return "[Bytecode Stub] VMInternal_ImplicitSetter"; - } else if (bytecode.raw() == - Object::implicit_static_getter_bytecode().raw()) { - return "[Bytecode Stub] VMInternal_ImplicitStaticGetter"; - } else if (bytecode.raw() == Object::method_extractor_bytecode().raw()) { - return "[Bytecode Stub] VMInternal_MethodExtractor"; - } else if (bytecode.raw() == Object::invoke_closure_bytecode().raw()) { - return "[Bytecode Stub] VMInternal_InvokeClosure"; - } else if (bytecode.raw() == Object::invoke_field_bytecode().raw()) { - return "[Bytecode Stub] VMInternal_InvokeField"; - } - return "[unknown stub]"; -} - -const char* Bytecode::Name() const { - Zone* zone = Thread::Current()->zone(); - const Function& fun = Function::Handle(zone, function()); - if (fun.IsNull()) { - return BytecodeStubName(*this); - } - const char* function_name = - String::Handle(zone, fun.UserVisibleName()).ToCString(); - return zone->PrintToString("[Bytecode] %s", function_name); -} - -const char* Bytecode::QualifiedName() const { - Zone* zone = Thread::Current()->zone(); - const Function& fun = Function::Handle(zone, function()); - if (fun.IsNull()) { - return BytecodeStubName(*this); - } - const char* function_name = - String::Handle(zone, fun.QualifiedScrubbedName()).ToCString(); - return zone->PrintToString("[Bytecode] %s", function_name); -} - -const char* Bytecode::FullyQualifiedName() const { - Zone* zone = Thread::Current()->zone(); - const Function& fun = Function::Handle(zone, function()); - if (fun.IsNull()) { - return BytecodeStubName(*this); - } - const char* function_name = fun.ToFullyQualifiedCString(); - return zone->PrintToString("[Bytecode] %s", function_name); -} - -bool Bytecode::SlowFindRawBytecodeVisitor::FindObject(ObjectPtr raw_obj) const { - return BytecodeLayout::ContainsPC(raw_obj, pc_); -} - -BytecodePtr Bytecode::FindCode(uword pc) { - Thread* thread = Thread::Current(); - HeapIterationScope heap_iteration_scope(thread); - SlowFindRawBytecodeVisitor visitor(pc); - ObjectPtr needle = thread->heap()->FindOldObject(&visitor); - if (needle != Bytecode::null()) { - return static_cast(needle); - } - return Bytecode::null(); -} - -LocalVarDescriptorsPtr Bytecode::GetLocalVarDescriptors() const { -#if defined(PRODUCT) || defined(DART_PRECOMPILED_RUNTIME) - UNREACHABLE(); - return LocalVarDescriptors::null(); -#else - Zone* zone = Thread::Current()->zone(); - auto& var_descs = LocalVarDescriptors::Handle(zone, var_descriptors()); - if (var_descs.IsNull()) { - const auto& func = Function::Handle(zone, function()); - ASSERT(!func.IsNull()); - var_descs = - kernel::BytecodeReader::ComputeLocalVarDescriptors(zone, func, *this); - ASSERT(!var_descs.IsNull()); - set_var_descriptors(var_descs); - } - return var_descs.raw(); -#endif -} - intptr_t Context::GetLevel() const { intptr_t level = 0; Context& parent_ctx = Context::Handle(parent()); @@ -24760,7 +24208,6 @@ const char* StackTrace::ToCString() const { auto& function = Function::Handle(zone); auto& code_object = Object::Handle(zone); auto& code = Code::Handle(zone); - auto& bytecode = Bytecode::Handle(zone); NoSafepointScope no_allocation; GrowableArray inlined_functions; @@ -24834,77 +24281,65 @@ const char* StackTrace::ToCString() const { buffer.AddString("\n"); } else { intptr_t pc_offset = Smi::Value(stack_trace.PcOffsetAtFrame(i)); - if (code_object.IsCode()) { - code ^= code_object.raw(); - ASSERT(code.IsFunctionCode()); - function = code.function(); - const uword pc = code.PayloadStart() + pc_offset; + ASSERT(code_object.IsCode()); + code ^= code_object.raw(); + ASSERT(code.IsFunctionCode()); + function = code.function(); + const uword pc = code.PayloadStart() + pc_offset; #if defined(DART_PRECOMPILED_RUNTIME) - // When printing non-symbolic frames, we normally print call - // addresses, not return addresses, by subtracting one from the PC to - // get an address within the preceding instruction. - // - // The one exception is a normal closure registered as a listener on a - // future. In this case, the returned pc_offset is 0, as the closure - // is invoked with the value of the resolved future. Thus, we must - // report the return address, as returning a value before the closure - // payload will cause failures to decode the frame using DWARF info. - const bool is_future_listener = pc_offset == 0; - const uword call_addr = is_future_listener ? pc : pc - 1; - if (FLAG_dwarf_stack_traces_mode) { - // If we have access to the owning function and it would be - // invisible in a symbolic stack trace, don't show this frame. - // (We can't do the same for inlined functions, though.) - if (!FLAG_show_invisible_frames && !function.IsNull() && - !function.is_visible()) { - continue; - } - // This output is formatted like Android's debuggerd. Note debuggerd - // prints call addresses instead of return addresses. - buffer.Printf(" #%02" Pd " abs %" Pp "", frame_index, call_addr); - PrintNonSymbolicStackFrameBody( - &buffer, call_addr, isolate_instructions, vm_instructions); - frame_index++; - continue; - } else if (function.IsNull()) { - // We can't print the symbolic information since the owner was not - // retained, so instead print the static symbol + offset like the - // non-symbolic stack traces. - PrintSymbolicStackFrameIndex(&buffer, frame_index); - PrintNonSymbolicStackFrameBody( - &buffer, call_addr, isolate_instructions, vm_instructions); - frame_index++; + // When printing non-symbolic frames, we normally print call + // addresses, not return addresses, by subtracting one from the PC to + // get an address within the preceding instruction. + // + // The one exception is a normal closure registered as a listener on a + // future. In this case, the returned pc_offset is 0, as the closure + // is invoked with the value of the resolved future. Thus, we must + // report the return address, as returning a value before the closure + // payload will cause failures to decode the frame using DWARF info. + const bool is_future_listener = pc_offset == 0; + const uword call_addr = is_future_listener ? pc : pc - 1; + if (FLAG_dwarf_stack_traces_mode) { + // If we have access to the owning function and it would be + // invisible in a symbolic stack trace, don't show this frame. + // (We can't do the same for inlined functions, though.) + if (!FLAG_show_invisible_frames && !function.IsNull() && + !function.is_visible()) { continue; } + // This output is formatted like Android's debuggerd. Note debuggerd + // prints call addresses instead of return addresses. + buffer.Printf(" #%02" Pd " abs %" Pp "", frame_index, call_addr); + PrintNonSymbolicStackFrameBody(&buffer, call_addr, + isolate_instructions, vm_instructions); + frame_index++; + continue; + } else if (function.IsNull()) { + // We can't print the symbolic information since the owner was not + // retained, so instead print the static symbol + offset like the + // non-symbolic stack traces. + PrintSymbolicStackFrameIndex(&buffer, frame_index); + PrintNonSymbolicStackFrameBody(&buffer, call_addr, + isolate_instructions, vm_instructions); + frame_index++; + continue; + } #endif - if (code.is_optimized() && stack_trace.expand_inlined()) { - code.GetInlinedFunctionsAtReturnAddress( - pc_offset, &inlined_functions, &inlined_token_positions); - ASSERT(inlined_functions.length() >= 1); - for (intptr_t j = inlined_functions.length() - 1; j >= 0; j--) { - const auto& inlined = *inlined_functions[j]; - auto const pos = inlined_token_positions[j]; - if (FLAG_show_invisible_frames || function.is_visible()) { - PrintSymbolicStackFrame(zone, &buffer, inlined, pos, - frame_index); - frame_index++; - } + if (code.is_optimized() && stack_trace.expand_inlined()) { + code.GetInlinedFunctionsAtReturnAddress(pc_offset, &inlined_functions, + &inlined_token_positions); + ASSERT(inlined_functions.length() >= 1); + for (intptr_t j = inlined_functions.length() - 1; j >= 0; j--) { + const auto& inlined = *inlined_functions[j]; + auto const pos = inlined_token_positions[j]; + if (FLAG_show_invisible_frames || function.is_visible()) { + PrintSymbolicStackFrame(zone, &buffer, inlined, pos, frame_index); + frame_index++; } - } else if (FLAG_show_invisible_frames || function.is_visible()) { - auto const pos = code.GetTokenIndexOfPC(pc); - PrintSymbolicStackFrame(zone, &buffer, function, pos, frame_index); - frame_index++; - } - } else { - ASSERT(code_object.IsBytecode()); - bytecode ^= code_object.raw(); - function = bytecode.function(); - if (FLAG_show_invisible_frames || function.is_visible()) { - uword pc = bytecode.PayloadStart() + pc_offset; - auto const pos = bytecode.GetTokenIndexOfPC(pc); - PrintSymbolicStackFrame(zone, &buffer, function, pos, frame_index); - frame_index++; } + } else if (FLAG_show_invisible_frames || function.is_visible()) { + auto const pos = code.GetTokenIndexOfPC(pc); + PrintSymbolicStackFrame(zone, &buffer, function, pos, frame_index); + frame_index++; } } } diff --git a/runtime/vm/object.h b/runtime/vm/object.h index 7d49951d696..903ad3d3e26 100644 --- a/runtime/vm/object.h +++ b/runtime/vm/object.h @@ -429,14 +429,6 @@ class Object { V(ExceptionHandlers, empty_exception_handlers) \ V(Array, extractor_parameter_types) \ V(Array, extractor_parameter_names) \ - V(Bytecode, implicit_getter_bytecode) \ - V(Bytecode, implicit_setter_bytecode) \ - V(Bytecode, implicit_static_getter_bytecode) \ - V(Bytecode, method_extractor_bytecode) \ - V(Bytecode, invoke_closure_bytecode) \ - V(Bytecode, invoke_field_bytecode) \ - V(Bytecode, nsm_dispatcher_bytecode) \ - V(Bytecode, dynamic_invocation_forwarder_bytecode) \ V(Instance, sentinel) \ V(Instance, transition_sentinel) \ V(Instance, unknown_constant) \ @@ -486,7 +478,6 @@ class Object { return kernel_program_info_class_; } static ClassPtr code_class() { return code_class_; } - static ClassPtr bytecode_class() { return bytecode_class_; } static ClassPtr instructions_class() { return instructions_class_; } static ClassPtr instructions_section_class() { return instructions_section_class_; @@ -510,7 +501,6 @@ class Object { return unhandled_exception_class_; } static ClassPtr unwind_error_class() { return unwind_error_class_; } - static ClassPtr dyncalltypecheck_class() { return dyncalltypecheck_class_; } static ClassPtr singletargetcache_class() { return singletargetcache_class_; } static ClassPtr unlinkedcall_class() { return unlinkedcall_class_; } static ClassPtr monomorphicsmiablecall_class() { @@ -792,7 +782,7 @@ class Object { static ClassPtr kernel_program_info_class_; // Class of KernelProgramInfo vm // object. static ClassPtr code_class_; // Class of the Code vm object. - static ClassPtr bytecode_class_; // Class of the Bytecode vm object. + static ClassPtr instructions_class_; // Class of the Instructions vm object. static ClassPtr instructions_section_class_; // Class of InstructionsSection. static ClassPtr object_pool_class_; // Class of the ObjectPool vm object. @@ -804,7 +794,6 @@ class Object { static ClassPtr deopt_info_class_; // Class of DeoptInfo. static ClassPtr context_class_; // Class of the Context vm object. static ClassPtr context_scope_class_; // Class of ContextScope vm object. - static ClassPtr dyncalltypecheck_class_; // Class of ParameterTypeCheck. static ClassPtr singletargetcache_class_; // Class of SingleTargetCache. static ClassPtr unlinkedcall_class_; // Class of UnlinkedCall. static ClassPtr @@ -1436,25 +1425,11 @@ class Class : public Object { CodePtr allocation_stub() const { return raw_ptr()->allocation_stub_; } void set_allocation_stub(const Code& value) const; -#if !defined(DART_PRECOMPILED_RUNTIME) - intptr_t binary_declaration_offset() const { - return ClassLayout::BinaryDeclarationOffset::decode( - raw_ptr()->binary_declaration_); - } - void set_binary_declaration_offset(intptr_t value) const { - ASSERT(value >= 0); - StoreNonPointer(&raw_ptr()->binary_declaration_, - ClassLayout::BinaryDeclarationOffset::update( - value, raw_ptr()->binary_declaration_)); - } -#endif // !defined(DART_PRECOMPILED_RUNTIME) - intptr_t kernel_offset() const { #if defined(DART_PRECOMPILED_RUNTIME) return 0; #else - ASSERT(!is_declared_in_bytecode()); - return binary_declaration_offset(); + return raw_ptr()->kernel_offset_; #endif } @@ -1462,46 +1437,11 @@ class Class : public Object { #if defined(DART_PRECOMPILED_RUNTIME) UNREACHABLE(); #else - ASSERT(!is_declared_in_bytecode()); - set_binary_declaration_offset(value); + ASSERT(value >= 0); + StoreNonPointer(&raw_ptr()->kernel_offset_, value); #endif } - intptr_t bytecode_offset() const { -#if defined(DART_PRECOMPILED_RUNTIME) - return 0; -#else - ASSERT(is_declared_in_bytecode()); - return binary_declaration_offset(); -#endif - } - - void set_bytecode_offset(intptr_t value) const { -#if defined(DART_PRECOMPILED_RUNTIME) - UNREACHABLE(); -#else - ASSERT(is_declared_in_bytecode()); - set_binary_declaration_offset(value); -#endif - } - - bool is_declared_in_bytecode() const { -#if defined(DART_PRECOMPILED_RUNTIME) - return false; -#else - return ClassLayout::IsDeclaredInBytecode::decode( - raw_ptr()->binary_declaration_); -#endif - } - -#if !defined(DART_PRECOMPILED_RUNTIME) - void set_is_declared_in_bytecode(bool value) const { - StoreNonPointer(&raw_ptr()->binary_declaration_, - ClassLayout::IsDeclaredInBytecode::update( - value, raw_ptr()->binary_declaration_)); - } -#endif // !defined(DART_PRECOMPILED_RUNTIME) - void DisableAllocationStub() const; ArrayPtr constants() const; @@ -1791,7 +1731,6 @@ class Class : public Object { friend class Instance; friend class Object; friend class Type; - friend class InterpreterHelpers; friend class Intrinsifier; friend class ProgramWalker; friend class Precompiler; @@ -1850,41 +1789,6 @@ class PatchClass : public Object { friend class Class; }; -class ParameterTypeCheck : public Object { - public: - // The FP-relative index of the parameter in a bytecode frame (after optional - // parameter marshalling) whose assignability needs to be checked, or 0 if - // this is a type parameter check. - intptr_t index() const { return raw_ptr()->index_; } - void set_index(intptr_t i) const { StoreNonPointer(&raw_ptr()->index_, i); } - - // The type parameter to whose bound needs to be checked, or null if this is - // an ordinary parameter check. - AbstractTypePtr param() const { return raw_ptr()->param_; } - void set_param(const AbstractType& t) const; - - // FP[index] assignable to type, OR param is subtype of bound. - AbstractTypePtr type_or_bound() const { return raw_ptr()->type_or_bound_; } - void set_type_or_bound(const AbstractType& t) const; - - // The parameter or type parameter's name to use in an error message. - StringPtr name() const { return raw_ptr()->name_; } - void set_name(const String& n) const; - - SubtypeTestCachePtr cache() const { return raw_ptr()->cache_; } - void set_cache(const SubtypeTestCache& c) const; - - static intptr_t InstanceSize() { - return RoundedAllocationSize(sizeof(ParameterTypeCheckLayout)); - } - - static ParameterTypeCheckPtr New(); - - private: - FINAL_HEAP_OBJECT_IMPLEMENTATION(ParameterTypeCheck, Object); - friend class Class; -}; - class SingleTargetCache : public Object { public: CodePtr target() const { return raw_ptr()->target_; } @@ -2424,7 +2328,6 @@ class ICData : public CallSiteData { friend class Class; friend class VMDeserializationRoots; friend class ICDataTestTask; - friend class Interpreter; friend class VMSerializationRoots; friend class SnapshotWriter; }; @@ -2693,7 +2596,6 @@ class Function : public Object { void AttachCode(const Code& value) const; void SetInstructions(const Code& value) const; void ClearCode() const; - void ClearBytecode() const; // Disables optimized code and switches to unoptimized code. void SwitchToUnoptimizedCode() const; @@ -2731,9 +2633,6 @@ class Function : public Object { void set_unoptimized_code(const Code& value) const; bool HasCode() const; static bool HasCode(FunctionPtr function); -#if !defined(DART_PRECOMPILED_RUNTIME) - static inline bool HasBytecode(FunctionPtr function); -#endif static intptr_t code_offset() { return OFFSET_OF(FunctionLayout, code_); } @@ -2757,15 +2656,6 @@ class Function : public Object { return OFFSET_OF(FunctionLayout, unchecked_entry_point_); } -#if !defined(DART_PRECOMPILED_RUNTIME) - bool IsBytecodeAllowed(Zone* zone) const; - void AttachBytecode(const Bytecode& bytecode) const; - BytecodePtr bytecode() const { return raw_ptr()->bytecode_; } - inline bool HasBytecode() const; -#else - inline bool HasBytecode() const { return false; } -#endif - virtual intptr_t Hash() const; // Returns true if there is at least one debugger breakpoint @@ -2952,10 +2842,6 @@ class Function : public Object { return (kind() == FunctionLayout::kConstructor) && is_static(); } - static bool ClosureBodiesContainNonCovariantTypeArgumentChecks() { - return FLAG_enable_interpreter; - } - static bool ClosureBodiesContainNonCovariantArgumentChecks() { return FLAG_precompiled_mode || FLAG_lazy_dispatchers; } @@ -3034,9 +2920,7 @@ class Function : public Object { } bool NeedsTypeArgumentTypeChecks() const { - return (IsClosureFunction() && - ClosureBodiesContainNonCovariantTypeArgumentChecks()) || - !(is_static() || (kind() == FunctionLayout::kConstructor)); + return !(is_static() || (kind() == FunctionLayout::kConstructor)); } bool NeedsMonomorphicCheckedEntry(Zone* zone) const; @@ -3140,25 +3024,11 @@ class Function : public Object { #undef DEFINE_GETTERS_AND_SETTERS -#if !defined(DART_PRECOMPILED_RUNTIME) - intptr_t binary_declaration_offset() const { - return FunctionLayout::BinaryDeclarationOffset::decode( - raw_ptr()->binary_declaration_); - } - void set_binary_declaration_offset(intptr_t value) const { - ASSERT(value >= 0); - StoreNonPointer(&raw_ptr()->binary_declaration_, - FunctionLayout::BinaryDeclarationOffset::update( - value, raw_ptr()->binary_declaration_)); - } -#endif // !defined(DART_PRECOMPILED_RUNTIME) - intptr_t kernel_offset() const { #if defined(DART_PRECOMPILED_RUNTIME) return 0; #else - ASSERT(!is_declared_in_bytecode()); - return binary_declaration_offset(); + return raw_ptr()->kernel_offset_; #endif } @@ -3166,48 +3036,13 @@ class Function : public Object { #if defined(DART_PRECOMPILED_RUNTIME) UNREACHABLE(); #else - ASSERT(!is_declared_in_bytecode()); - set_binary_declaration_offset(value); + ASSERT(value >= 0); + StoreNonPointer(&raw_ptr()->kernel_offset_, value); #endif } - intptr_t bytecode_offset() const { -#if defined(DART_PRECOMPILED_RUNTIME) - return 0; -#else - ASSERT(is_declared_in_bytecode()); - return binary_declaration_offset(); -#endif - } - - void set_bytecode_offset(intptr_t value) const { -#if defined(DART_PRECOMPILED_RUNTIME) - UNREACHABLE(); -#else - ASSERT(is_declared_in_bytecode()); - set_binary_declaration_offset(value); -#endif - } - - bool is_declared_in_bytecode() const { -#if defined(DART_PRECOMPILED_RUNTIME) - return false; -#else - return FunctionLayout::IsDeclaredInBytecode::decode( - raw_ptr()->binary_declaration_); -#endif - } - -#if !defined(DART_PRECOMPILED_RUNTIME) - void set_is_declared_in_bytecode(bool value) const { - StoreNonPointer(&raw_ptr()->binary_declaration_, - FunctionLayout::IsDeclaredInBytecode::update( - value, raw_ptr()->binary_declaration_)); - } -#endif // !defined(DART_PRECOMPILED_RUNTIME) - - void InheritBinaryDeclarationFrom(const Function& src) const; - void InheritBinaryDeclarationFrom(const Field& src) const; + void InheritKernelOffsetFrom(const Function& src) const; + void InheritKernelOffsetFrom(const Field& src) const; static const intptr_t kMaxInstructionCount = (1 << 16) - 1; @@ -3256,9 +3091,6 @@ class Function : public Object { bool HasOptimizedCode() const; - // Whether the function is ready for compiler optimizations. - bool ShouldCompilerOptimize() const; - // Returns true if the argument counts are valid for calling this function. // Otherwise, it returns false and the reason (if error_message is not NULL). bool AreValidArgumentCounts(intptr_t num_type_arguments, @@ -4206,25 +4038,11 @@ class Field : public Object { GenericCovariantImplBit::update(value, raw_ptr()->kind_bits_)); } -#if !defined(DART_PRECOMPILED_RUNTIME) - intptr_t binary_declaration_offset() const { - return FieldLayout::BinaryDeclarationOffset::decode( - raw_ptr()->binary_declaration_); - } - void set_binary_declaration_offset(intptr_t value) const { - ASSERT(value >= 0); - StoreNonPointer(&raw_ptr()->binary_declaration_, - FieldLayout::BinaryDeclarationOffset::update( - value, raw_ptr()->binary_declaration_)); - } -#endif // !defined(DART_PRECOMPILED_RUNTIME) - intptr_t kernel_offset() const { #if defined(DART_PRECOMPILED_RUNTIME) return 0; #else - ASSERT(!is_declared_in_bytecode()); - return binary_declaration_offset(); + return raw_ptr()->kernel_offset_; #endif } @@ -4232,47 +4050,12 @@ class Field : public Object { #if defined(DART_PRECOMPILED_RUNTIME) UNREACHABLE(); #else - ASSERT(!is_declared_in_bytecode()); - set_binary_declaration_offset(value); + ASSERT(value >= 0); + StoreNonPointer(&raw_ptr()->kernel_offset_, value); #endif } - intptr_t bytecode_offset() const { -#if defined(DART_PRECOMPILED_RUNTIME) - return 0; -#else - ASSERT(is_declared_in_bytecode()); - return binary_declaration_offset(); -#endif - } - - void set_bytecode_offset(intptr_t value) const { -#if defined(DART_PRECOMPILED_RUNTIME) - UNREACHABLE(); -#else - ASSERT(is_declared_in_bytecode()); - set_binary_declaration_offset(value); -#endif - } - - bool is_declared_in_bytecode() const { -#if defined(DART_PRECOMPILED_RUNTIME) - return false; -#else - return FieldLayout::IsDeclaredInBytecode::decode( - raw_ptr()->binary_declaration_); -#endif - } - -#if !defined(DART_PRECOMPILED_RUNTIME) - void set_is_declared_in_bytecode(bool value) const { - StoreNonPointer(&raw_ptr()->binary_declaration_, - FieldLayout::IsDeclaredInBytecode::update( - value, raw_ptr()->binary_declaration_)); - } -#endif // !defined(DART_PRECOMPILED_RUNTIME) - - void InheritBinaryDeclarationFrom(const Field& src) const; + void InheritKernelOffsetFrom(const Field& src) const; ExternalTypedDataPtr KernelData() const; @@ -4600,7 +4383,6 @@ class Field : public Object { const Object& owner, TokenPosition token_pos, TokenPosition end_token_pos); - friend class Interpreter; // Access to bit field. friend class StoreInstanceFieldInstr; // Generated code access to bit field. enum { @@ -4947,27 +4729,22 @@ class Library : public Object { void AddClassMetadata(const Class& cls, const Object& tl_owner, TokenPosition token_pos, - intptr_t kernel_offset, - intptr_t bytecode_offset) const; + intptr_t kernel_offset) const; void AddFieldMetadata(const Field& field, TokenPosition token_pos, - intptr_t kernel_offset, - intptr_t bytecode_offset) const; + intptr_t kernel_offset) const; void AddFunctionMetadata(const Function& func, TokenPosition token_pos, - intptr_t kernel_offset, - intptr_t bytecode_offset) const; + intptr_t kernel_offset) const; void AddLibraryMetadata(const Object& tl_owner, TokenPosition token_pos, - intptr_t kernel_offset, - intptr_t bytecode_offset) const; + intptr_t kernel_offset) const; void AddTypeParameterMetadata(const TypeParameter& param, TokenPosition token_pos) const; void CloneMetadataFrom(const Library& from_library, const Function& from_fun, const Function& to_fun) const; ObjectPtr GetMetadata(const Object& obj) const; - ArrayPtr GetExtendedMetadata(const Object& obj, intptr_t count) const; // Tries to finds a @pragma annotation on [object]. // @@ -5089,25 +4866,11 @@ class Library : public Object { ExternalTypedDataPtr kernel_data() const { return raw_ptr()->kernel_data_; } void set_kernel_data(const ExternalTypedData& data) const; -#if !defined(DART_PRECOMPILED_RUNTIME) - intptr_t binary_declaration_offset() const { - return LibraryLayout::BinaryDeclarationOffset::decode( - raw_ptr()->binary_declaration_); - } - void set_binary_declaration_offset(intptr_t value) const { - ASSERT(value >= 0); - StoreNonPointer(&raw_ptr()->binary_declaration_, - LibraryLayout::BinaryDeclarationOffset::update( - value, raw_ptr()->binary_declaration_)); - } -#endif // !defined(DART_PRECOMPILED_RUNTIME) - intptr_t kernel_offset() const { #if defined(DART_PRECOMPILED_RUNTIME) return 0; #else - ASSERT(!is_declared_in_bytecode()); - return binary_declaration_offset(); + return raw_ptr()->kernel_offset_; #endif } @@ -5115,46 +4878,11 @@ class Library : public Object { #if defined(DART_PRECOMPILED_RUNTIME) UNREACHABLE(); #else - ASSERT(!is_declared_in_bytecode()); - set_binary_declaration_offset(value); + ASSERT(value >= 0); + StoreNonPointer(&raw_ptr()->kernel_offset_, value); #endif } - intptr_t bytecode_offset() const { -#if defined(DART_PRECOMPILED_RUNTIME) - return 0; -#else - ASSERT(is_declared_in_bytecode()); - return binary_declaration_offset(); -#endif - } - - void set_bytecode_offset(intptr_t value) const { -#if defined(DART_PRECOMPILED_RUNTIME) - UNREACHABLE(); -#else - ASSERT(is_declared_in_bytecode()); - set_binary_declaration_offset(value); -#endif - } - - bool is_declared_in_bytecode() const { -#if defined(DART_PRECOMPILED_RUNTIME) - return false; -#else - return LibraryLayout::IsDeclaredInBytecode::decode( - raw_ptr()->binary_declaration_); -#endif - } - -#if !defined(DART_PRECOMPILED_RUNTIME) - void set_is_declared_in_bytecode(bool value) const { - StoreNonPointer(&raw_ptr()->binary_declaration_, - LibraryLayout::IsDeclaredInBytecode::update( - value, raw_ptr()->binary_declaration_)); - } -#endif // !defined(DART_PRECOMPILED_RUNTIME) - static LibraryPtr LookupLibrary(Thread* thread, const String& url); static LibraryPtr GetLibrary(intptr_t index); @@ -5184,8 +4912,6 @@ class Library : public Object { #if !defined(DART_PRECOMPILED_RUNTIME) // Finalize all classes in all libraries. static ErrorPtr FinalizeAllClasses(); - // Eagerly read all bytecode. - static ErrorPtr ReadAllBytecode(); #endif #if defined(DEBUG) && !defined(DART_PRECOMPILED_RUNTIME) @@ -5278,8 +5004,7 @@ class Library : public Object { void AddMetadata(const Object& owner, const String& name, TokenPosition token_pos, - intptr_t kernel_offset, - intptr_t bytecode_offset) const; + intptr_t kernel_offset) const; FINAL_HEAP_OBJECT_IMPLEMENTATION(Library, Object); @@ -5411,9 +5136,6 @@ class KernelProgramInfo : public Object { const Smi& name_index, const Class& klass) const; - ArrayPtr bytecode_component() const { return raw_ptr()->bytecode_component_; } - void set_bytecode_component(const Array& bytecode_component) const; - private: static KernelProgramInfoPtr New(); @@ -5486,15 +5208,13 @@ class ObjectPool : public Object { template ObjectPtr ObjectAt(intptr_t index) const { - ASSERT((TypeAt(index) == EntryType::kTaggedObject) || - (TypeAt(index) == EntryType::kNativeEntryData)); + ASSERT(TypeAt(index) == EntryType::kTaggedObject); return LoadPointer(&(EntryAddr(index)->raw_obj_)); } template void SetObjectAt(intptr_t index, const Object& obj) const { ASSERT((TypeAt(index) == EntryType::kTaggedObject) || - (TypeAt(index) == EntryType::kNativeEntryData) || (TypeAt(index) == EntryType::kImmediate && obj.IsSmi())); StorePointer(&EntryAddr(index)->raw_obj_, obj.raw()); } @@ -6920,151 +6640,6 @@ class Code : public Object { friend class CodeKeyValueTrait; // for UncheckedEntryPointOffset }; -class Bytecode : public Object { - public: - uword instructions() const { return raw_ptr()->instructions_; } - - uword PayloadStart() const { return instructions(); } - intptr_t Size() const { return raw_ptr()->instructions_size_; } - - ObjectPoolPtr object_pool() const { return raw_ptr()->object_pool_; } - - bool ContainsInstructionAt(uword addr) const { - return BytecodeLayout::ContainsPC(raw(), addr); - } - - PcDescriptorsPtr pc_descriptors() const { return raw_ptr()->pc_descriptors_; } - void set_pc_descriptors(const PcDescriptors& descriptors) const { - ASSERT(descriptors.IsOld()); - StorePointer(&raw_ptr()->pc_descriptors_, descriptors.raw()); - } - - void Disassemble(DisassemblyFormatter* formatter = NULL) const; - - ExceptionHandlersPtr exception_handlers() const { - return raw_ptr()->exception_handlers_; - } - void set_exception_handlers(const ExceptionHandlers& handlers) const { - ASSERT(handlers.IsOld()); - StorePointer(&raw_ptr()->exception_handlers_, handlers.raw()); - } - - FunctionPtr function() const { return raw_ptr()->function_; } - - void set_function(const Function& function) const { - ASSERT(function.IsOld()); - StorePointer(&raw_ptr()->function_, function.raw()); - } - - static intptr_t InstanceSize() { - return RoundedAllocationSize(sizeof(BytecodeLayout)); - } - static BytecodePtr New(uword instructions, - intptr_t instructions_size, - intptr_t instructions_offset, - const ObjectPool& object_pool); - - ExternalTypedDataPtr GetBinary(Zone* zone) const; - - TokenPosition GetTokenIndexOfPC(uword return_address) const; - intptr_t GetTryIndexAtPc(uword return_address) const; - - // Return the pc of the first 'DebugCheck' opcode of the bytecode. - // Return 0 if none is found. - uword GetFirstDebugCheckOpcodePc() const; - - // Return the pc after the first 'debug checked' opcode in the range. - // Return 0 if none is found. - uword GetDebugCheckedOpcodeReturnAddress(uword from_offset, - uword to_offset) const; - - intptr_t instructions_binary_offset() const { - return raw_ptr()->instructions_binary_offset_; - } - void set_instructions_binary_offset(intptr_t value) const { - StoreNonPointer(&raw_ptr()->instructions_binary_offset_, value); - } - - intptr_t source_positions_binary_offset() const { - return raw_ptr()->source_positions_binary_offset_; - } - void set_source_positions_binary_offset(intptr_t value) const { - StoreNonPointer(&raw_ptr()->source_positions_binary_offset_, value); - } - bool HasSourcePositions() const { - return (source_positions_binary_offset() != 0); - } - - intptr_t local_variables_binary_offset() const { - return raw_ptr()->local_variables_binary_offset_; - } - void set_local_variables_binary_offset(intptr_t value) const { - StoreNonPointer(&raw_ptr()->local_variables_binary_offset_, value); - } - bool HasLocalVariablesInfo() const { - return (local_variables_binary_offset() != 0); - } - - LocalVarDescriptorsPtr var_descriptors() const { -#if defined(PRODUCT) - UNREACHABLE(); - return nullptr; -#else - return raw_ptr()->var_descriptors_; -#endif - } - void set_var_descriptors(const LocalVarDescriptors& value) const { -#if defined(PRODUCT) - UNREACHABLE(); -#else - ASSERT(value.IsOld()); - StorePointer(&raw_ptr()->var_descriptors_, value.raw()); -#endif - } - - // Will compute local var descriptors if necessary. - LocalVarDescriptorsPtr GetLocalVarDescriptors() const; - - const char* Name() const; - const char* QualifiedName() const; - const char* FullyQualifiedName() const; - - class SlowFindRawBytecodeVisitor : public FindObjectVisitor { - public: - explicit SlowFindRawBytecodeVisitor(uword pc) : pc_(pc) {} - virtual ~SlowFindRawBytecodeVisitor() {} - - // Check if object matches find condition. - virtual bool FindObject(ObjectPtr obj) const; - - private: - const uword pc_; - - DISALLOW_COPY_AND_ASSIGN(SlowFindRawBytecodeVisitor); - }; - - static BytecodePtr FindCode(uword pc); - - private: - void set_instructions(uword instructions) const { - StoreNonPointer(&raw_ptr()->instructions_, instructions); - } - void set_instructions_size(intptr_t size) const { - StoreNonPointer(&raw_ptr()->instructions_size_, size); - } - void set_object_pool(const ObjectPool& object_pool) const { - StorePointer(&raw_ptr()->object_pool_, object_pool.raw()); - } - - friend class BytecodeDeserializationCluster; - friend class ObjectLayout; // For ObjectLayout::SizeFromClass(). - friend class BytecodeLayout; - - FINAL_HEAP_OBJECT_IMPLEMENTATION(Bytecode, Object); - friend class Class; - friend class SnapshotWriter; -}; - class Context : public Object { public: ContextPtr parent() const { return raw_ptr()->parent_; } @@ -10038,7 +9613,6 @@ class Array : public Instance { FINAL_HEAP_OBJECT_IMPLEMENTATION(Array, Instance); friend class Class; friend class ImmutableArray; - friend class Interpreter; friend class Object; friend class String; }; @@ -11492,16 +11066,6 @@ void Object::SetRaw(ObjectPtr value) { #endif } -#if !defined(DART_PRECOMPILED_RUNTIME) -bool Function::HasBytecode() const { - return raw_ptr()->bytecode_ != Bytecode::null(); -} - -bool Function::HasBytecode(FunctionPtr function) { - return function->ptr()->bytecode_ != Bytecode::null(); -} -#endif // !defined(DART_PRECOMPILED_RUNTIME) - intptr_t Field::HostOffset() const { ASSERT(is_instance()); // Valid only for dart instance fields. return (Smi::Value(raw_ptr()->host_offset_or_field_id_) * kWordSize); diff --git a/runtime/vm/object_reload.cc b/runtime/vm/object_reload.cc index 866ae6ca98c..bea8d1408a7 100644 --- a/runtime/vm/object_reload.cc +++ b/runtime/vm/object_reload.cc @@ -176,57 +176,6 @@ void CallSiteResetter::ResetSwitchableCalls(const Code& code) { } } -void CallSiteResetter::RebindStaticTargets(const Bytecode& bytecode) { - // Iterate over the Bytecode's object pool and reset all ICDatas. - pool_ = bytecode.object_pool(); - ASSERT(!pool_.IsNull()); - - for (intptr_t i = 0; i < pool_.Length(); i++) { - ObjectPool::EntryType entry_type = pool_.TypeAt(i); - if (entry_type != ObjectPool::EntryType::kTaggedObject) { - continue; - } - object_ = pool_.ObjectAt(i); - if (object_.IsFunction()) { - const Function& old_function = Function::Cast(object_); - if (old_function.IsClosureFunction()) { - continue; - } - name_ = old_function.name(); - new_cls_ = old_function.Owner(); - if (new_cls_.IsTopLevel()) { - new_lib_ = new_cls_.library(); - new_function_ = new_lib_.LookupLocalFunction(name_); - } else { - new_function_ = Resolver::ResolveFunction(zone_, new_cls_, name_); - } - if (!new_function_.IsNull() && - (new_function_.is_static() == old_function.is_static()) && - (new_function_.kind() == old_function.kind())) { - pool_.SetObjectAt(i, new_function_); - } else { - VTIR_Print("Cannot rebind function %s\n", old_function.ToCString()); - } - } else if (object_.IsField()) { - const Field& old_field = Field::Cast(object_); - name_ = old_field.name(); - new_cls_ = old_field.Owner(); - if (new_cls_.IsTopLevel()) { - new_lib_ = new_cls_.library(); - new_field_ = new_lib_.LookupLocalField(name_); - } else { - new_field_ = new_cls_.LookupField(name_); - } - if (!new_field_.IsNull() && - (new_field_.is_static() == old_field.is_static())) { - pool_.SetObjectAt(i, new_field_); - } else { - VTIR_Print("Cannot rebind field %s\n", old_field.ToCString()); - } - } - } -} - void CallSiteResetter::ResetCaches(const ObjectPool& pool) { for (intptr_t i = 0; i < pool.Length(); i++) { ObjectPool::EntryType entry_type = pool.TypeAt(i); @@ -493,10 +442,8 @@ void Class::PatchFieldsAndFunctions() const { PatchClass::Handle(PatchClass::New(*this, Script::Handle(script()))); ASSERT(!patch.IsNull()); const Library& lib = Library::Handle(library()); - if (!lib.is_declared_in_bytecode()) { - patch.set_library_kernel_data(ExternalTypedData::Handle(lib.kernel_data())); - patch.set_library_kernel_offset(lib.kernel_offset()); - } + patch.set_library_kernel_data(ExternalTypedData::Handle(lib.kernel_data())); + patch.set_library_kernel_offset(lib.kernel_offset()); const Array& funcs = Array::Handle(current_functions()); Function& func = Function::Handle(); diff --git a/runtime/vm/object_service.cc b/runtime/vm/object_service.cc index 8657d80cf7c..0d6553eff79 100644 --- a/runtime/vm/object_service.cc +++ b/runtime/vm/object_service.cc @@ -321,12 +321,6 @@ void Function::PrintJSONImpl(JSONStream* stream, bool ref) const { if (!code.IsNull()) { jsobj.AddProperty("code", code); } -#if !defined(DART_PRECOMPILED_RUNTIME) - Bytecode& bytecode = Bytecode::Handle(this->bytecode()); - if (!bytecode.IsNull()) { - jsobj.AddProperty("_bytecode", bytecode); - } -#endif // !DART_PRECOMPILED_RUNTIME Array& ics = Array::Handle(ic_data_array()); if (!ics.IsNull()) { jsobj.AddProperty("_icDataArray", ics); @@ -575,53 +569,6 @@ void Library::PrintJSONImpl(JSONStream* stream, bool ref) const { } } } - - if (is_declared_in_bytecode()) { - // Make sure top level class (containing annotations) is fully loaded. - EnsureTopLevelClassIsFinalized(); - Array& metadata = Array::Handle(GetExtendedMetadata(*this, 1)); - if (metadata.Length() != 0) { - // Library has the only element in the extended metadata. - metadata ^= metadata.At(0); - if (!metadata.IsNull()) { - Thread* thread = Thread::Current(); - auto& desc = Array::Handle(); - auto& target_uri = String::Handle(); - auto& is_export = Bool::Handle(); - auto& is_deferred = Bool::Handle(); - for (intptr_t i = 0, n = metadata.Length(); i < n; ++i) { - desc ^= metadata.At(i); - // Each dependency is represented as an array with the following - // layout: - // [0] = target library URI (String) - // [1] = is_export (bool) - // [2] = is_deferred (bool) - // [3] = prefix (String or null) - // ... - // The library dependencies are encoded by getLibraryAnnotations(), - // pkg/vm/lib/bytecode/gen_bytecode.dart. - target_uri ^= desc.At(0); - is_export ^= desc.At(1); - is_deferred ^= desc.At(2); - prefix_name ^= desc.At(3); - - target = Library::LookupLibrary(thread, target_uri); - if (target.IsNull()) { - continue; - } - - JSONObject jsdep(&jsarr); - jsdep.AddProperty("isDeferred", is_deferred.value()); - jsdep.AddProperty("isExport", is_export.value()); - jsdep.AddProperty("isImport", !is_export.value()); - if (!prefix_name.IsNull()) { - jsdep.AddProperty("prefix", prefix_name.ToCString()); - } - jsdep.AddProperty("target", target); - } - } - } - } } { JSONArray jsarr(&jsobj, "variables"); @@ -723,11 +670,6 @@ void ObjectPool::PrintJSONImpl(JSONStream* stream, bool ref) const { jsentry.AddProperty("kind", "Immediate"); jsentry.AddProperty64("value", imm); break; - case ObjectPool::EntryType::kNativeEntryData: - obj = ObjectAt(i); - jsentry.AddProperty("kind", "NativeEntryData"); - jsentry.AddProperty("value", obj); - break; case ObjectPool::EntryType::kNativeFunction: imm = RawValueAt(i); jsentry.AddProperty("kind", "NativeFunction"); @@ -809,10 +751,6 @@ void ExceptionHandlers::PrintJSONImpl(JSONStream* stream, bool ref) const { Object::PrintJSONImpl(stream, ref); } -void ParameterTypeCheck::PrintJSONImpl(JSONStream* stream, bool ref) const { - Object::PrintJSONImpl(stream, ref); -} - void SingleTargetCache::PrintJSONImpl(JSONStream* stream, bool ref) const { JSONObject jsobj(stream); AddCommonObjectProperties(&jsobj, "Object", ref); @@ -894,8 +832,6 @@ void ICData::PrintToJSONArray(const JSONArray& jsarray, } void Code::PrintJSONImpl(JSONStream* stream, bool ref) const { - // N.B. This is polymorphic with Bytecode. - JSONObject jsobj(stream); AddCommonObjectProperties(&jsobj, "Code", ref); jsobj.AddFixedServiceId("code/%" Px64 "-%" Px "", compile_timestamp(), @@ -957,47 +893,6 @@ void Code::PrintJSONImpl(JSONStream* stream, bool ref) const { PrintJSONInlineIntervals(&jsobj); } -void Bytecode::PrintJSONImpl(JSONStream* stream, bool ref) const { - // N.B. This is polymorphic with Code. - - JSONObject jsobj(stream); - AddCommonObjectProperties(&jsobj, "Code", ref); - int64_t compile_timestamp = 0; - jsobj.AddFixedServiceId("code/%" Px64 "-%" Px "", compile_timestamp, - PayloadStart()); - const char* qualified_name = QualifiedName(); - const char* vm_name = Name(); - AddNameProperties(&jsobj, qualified_name, vm_name); - - jsobj.AddProperty("kind", "Dart"); - jsobj.AddProperty("_optimized", false); - jsobj.AddProperty("_intrinsic", false); - jsobj.AddProperty("_native", false); - if (ref) { - return; - } - const Function& fun = Function::Handle(function()); - jsobj.AddProperty("function", fun); - jsobj.AddPropertyF("_startAddress", "%" Px "", PayloadStart()); - jsobj.AddPropertyF("_endAddress", "%" Px "", PayloadStart() + Size()); - jsobj.AddProperty("_alive", true); - const ObjectPool& obj_pool = ObjectPool::Handle(object_pool()); - jsobj.AddProperty("_objectPool", obj_pool); - { - JSONArray jsarr(&jsobj, "_disassembly"); - DisassembleToJSONStream formatter(jsarr); - Disassemble(&formatter); - } - const PcDescriptors& descriptors = PcDescriptors::Handle(pc_descriptors()); - if (!descriptors.IsNull()) { - JSONObject desc(&jsobj, "_descriptors"); - descriptors.PrintToJSONObject(&desc, false); - } - - { JSONArray inlined_functions(&jsobj, "_inlinedFunctions"); } - { JSONArray inline_intervals(&jsobj, "_inlinedIntervals"); } -} - void Context::PrintJSONImpl(JSONStream* stream, bool ref) const { JSONObject jsobj(stream); // TODO(turnidge): Should the user level type for Context be Context diff --git a/runtime/vm/object_store.h b/runtime/vm/object_store.h index f436b1a8fbc..dc51e07e0a1 100644 --- a/runtime/vm/object_store.h +++ b/runtime/vm/object_store.h @@ -170,7 +170,6 @@ class ObjectPointerVisitor; RW(Function, async_star_move_next_helper) \ RW(Function, complete_on_async_return) \ RW(Class, async_star_stream_controller) \ - RW(Array, bytecode_attributes) \ RW(GrowableObjectArray, llvm_constant_pool) \ RW(GrowableObjectArray, llvm_function_pool) \ RW(Array, llvm_constant_hash_table) \ diff --git a/runtime/vm/parser.cc b/runtime/vm/parser.cc index 4941d60c5e6..f4bf1341469 100644 --- a/runtime/vm/parser.cc +++ b/runtime/vm/parser.cc @@ -308,12 +308,6 @@ void ParsedFunction::AllocateIrregexpVariables(intptr_t num_stack_locals) { num_stack_locals_ = num_stack_locals; } -void ParsedFunction::AllocateBytecodeVariables(intptr_t num_stack_locals) { - ASSERT(!function().IsIrregexpFunction()); - first_parameter_index_ = VariableIndex(function().num_fixed_parameters()); - num_stack_locals_ = num_stack_locals; -} - void ParsedFunction::SetCovariantParameters( const BitVector* covariant_parameters) { ASSERT(covariant_parameters_ == nullptr); diff --git a/runtime/vm/parser.h b/runtime/vm/parser.h index 42eaf4b9278..76b6249ff9b 100644 --- a/runtime/vm/parser.h +++ b/runtime/vm/parser.h @@ -165,7 +165,6 @@ class ParsedFunction : public ZoneAllocated { void AllocateVariables(); void AllocateIrregexpVariables(intptr_t num_stack_locals); - void AllocateBytecodeVariables(intptr_t num_stack_locals); void record_await() { have_seen_await_expr_ = true; } bool have_seen_await() const { return have_seen_await_expr_; } diff --git a/runtime/vm/profiler.cc b/runtime/vm/profiler.cc index bc8199fa9e9..d12a7635eb2 100644 --- a/runtime/vm/profiler.cc +++ b/runtime/vm/profiler.cc @@ -557,16 +557,6 @@ class ProfilerDartStackWalker : public ProfilerStackWalker { pc_(reinterpret_cast(pc)), fp_(reinterpret_cast(fp)) {} - bool IsInterpretedFrame(uword* fp) { -#if defined(DART_PRECOMPILED_RUNTIME) - return false; -#else - Interpreter* interpreter = thread_->interpreter(); - if (interpreter == nullptr) return false; - return interpreter->HasFrame(reinterpret_cast(fp)); -#endif - } - void walk() { RELEASE_ASSERT(StubCode::HasBeenInitialized()); if (thread_->isolate()->IsDeoptimizing()) { @@ -575,45 +565,21 @@ class ProfilerDartStackWalker : public ProfilerStackWalker { } uword* exit_fp = reinterpret_cast(thread_->top_exit_frame_info()); - bool in_interpreted_frame; bool has_exit_frame = exit_fp != 0; if (has_exit_frame) { - if (IsInterpretedFrame(exit_fp)) { - // Exited from interpreter. - pc_ = 0; - fp_ = exit_fp; - in_interpreted_frame = true; - RELEASE_ASSERT(IsInterpretedFrame(fp_)); - } else { - // Exited from compiled code. - pc_ = 0; - fp_ = exit_fp; - in_interpreted_frame = false; - } + // Exited from compiled code. + pc_ = 0; + fp_ = exit_fp; // Skip exit frame. - pc_ = CallerPC(in_interpreted_frame); - fp_ = CallerFP(in_interpreted_frame); + pc_ = CallerPC(); + fp_ = CallerFP(); - // Can only move between interpreted and compiled frames after an exit - // frame. - RELEASE_ASSERT(IsInterpretedFrame(fp_) == in_interpreted_frame); } else { - if (thread_->vm_tag() == VMTag::kDartCompiledTagId) { + if (thread_->vm_tag() == VMTag::kDartTagId) { // Running compiled code. // Use the FP and PC from the thread interrupt or simulator; already set // in the constructor. - in_interpreted_frame = false; - } else if (thread_->vm_tag() == VMTag::kDartInterpretedTagId) { - // Running interpreter. -#if defined(DART_PRECOMPILED_RUNTIME) - UNREACHABLE(); -#else - pc_ = reinterpret_cast(thread_->interpreter()->get_pc()); - fp_ = reinterpret_cast(thread_->interpreter()->get_fp()); -#endif - in_interpreted_frame = true; - RELEASE_ASSERT(IsInterpretedFrame(fp_)); } else { // No Dart on the stack; caller shouldn't use this walker. UNREACHABLE(); @@ -622,8 +588,7 @@ class ProfilerDartStackWalker : public ProfilerStackWalker { sample_->set_exit_frame_sample(has_exit_frame); - if (!has_exit_frame && !in_interpreted_frame && - (CallerPC(in_interpreted_frame) == EntryMarker(in_interpreted_frame))) { + if (!has_exit_frame && (CallerPC() == EntryMarker())) { // During the prologue of a function, CallerPC will return the caller's // caller. For most frames, the missing PC will be added during profile // processing. However, during this stack walk, it can cause us to fail @@ -637,62 +602,53 @@ class ProfilerDartStackWalker : public ProfilerStackWalker { for (;;) { // Skip entry frame. - if (StubCode::InInvocationStub(reinterpret_cast(pc_), - in_interpreted_frame)) { + if (StubCode::InInvocationStub(reinterpret_cast(pc_))) { pc_ = 0; - fp_ = ExitLink(in_interpreted_frame); + fp_ = ExitLink(); if (fp_ == 0) { break; // End of Dart stack. } - in_interpreted_frame = IsInterpretedFrame(fp_); // Skip exit frame. - pc_ = CallerPC(in_interpreted_frame); - fp_ = CallerFP(in_interpreted_frame); + pc_ = CallerPC(); + fp_ = CallerFP(); // At least one frame between exit and next entry frame. - RELEASE_ASSERT(!StubCode::InInvocationStub(reinterpret_cast(pc_), - in_interpreted_frame)); + RELEASE_ASSERT( + !StubCode::InInvocationStub(reinterpret_cast(pc_))); } if (!Append(reinterpret_cast(pc_), reinterpret_cast(fp_))) { break; // Sample is full. } - pc_ = CallerPC(in_interpreted_frame); - fp_ = CallerFP(in_interpreted_frame); - - // Can only move between interpreted and compiled frames after an exit - // frame. - RELEASE_ASSERT(IsInterpretedFrame(fp_) == in_interpreted_frame); + pc_ = CallerPC(); + fp_ = CallerFP(); } } private: - uword* CallerPC(bool interp) const { + uword* CallerPC() const { ASSERT(fp_ != NULL); - uword* caller_pc_ptr = - fp_ + (interp ? kKBCSavedCallerPcSlotFromFp : kSavedCallerPcSlotFromFp); + uword* caller_pc_ptr = fp_ + kSavedCallerPcSlotFromFp; // MSan/ASan are unaware of frames initialized by generated code. MSAN_UNPOISON(caller_pc_ptr, kWordSize); ASAN_UNPOISON(caller_pc_ptr, kWordSize); return reinterpret_cast(*caller_pc_ptr); } - uword* CallerFP(bool interp) const { + uword* CallerFP() const { ASSERT(fp_ != NULL); - uword* caller_fp_ptr = - fp_ + (interp ? kKBCSavedCallerFpSlotFromFp : kSavedCallerFpSlotFromFp); + uword* caller_fp_ptr = fp_ + kSavedCallerFpSlotFromFp; // MSan/ASan are unaware of frames initialized by generated code. MSAN_UNPOISON(caller_fp_ptr, kWordSize); ASAN_UNPOISON(caller_fp_ptr, kWordSize); return reinterpret_cast(*caller_fp_ptr); } - uword* ExitLink(bool interp) const { + uword* ExitLink() const { ASSERT(fp_ != NULL); - uword* exit_link_ptr = - fp_ + (interp ? kKBCExitLinkSlotFromEntryFp : kExitLinkSlotFromEntryFp); + uword* exit_link_ptr = fp_ + kExitLinkSlotFromEntryFp; // MSan/ASan are unaware of frames initialized by generated code. MSAN_UNPOISON(exit_link_ptr, kWordSize); ASAN_UNPOISON(exit_link_ptr, kWordSize); @@ -701,8 +657,7 @@ class ProfilerDartStackWalker : public ProfilerStackWalker { // Note because of stack guards, it is important that this marker lives // above FP. - uword* EntryMarker(bool interp) const { - ASSERT(!interp); + uword* EntryMarker() const { ASSERT(fp_ != NULL); uword* entry_marker_ptr = fp_ + kSavedCallerPcSlotFromFp + 1; // MSan/ASan are unaware of frames initialized by generated code. @@ -1454,8 +1409,6 @@ class CodeLookupTableBuilder : public ObjectVisitor { void VisitObject(ObjectPtr raw_obj) { if (raw_obj->IsCode()) { table_->Add(Code::Handle(Code::RawCast(raw_obj))); - } else if (raw_obj->IsBytecode()) { - table_->Add(Bytecode::Handle(Bytecode::RawCast(raw_obj))); } } @@ -1506,7 +1459,7 @@ void CodeLookupTable::Build(Thread* thread) { void CodeLookupTable::Add(const Object& code) { ASSERT(!code.IsNull()); - ASSERT(code.IsCode() || code.IsBytecode()); + ASSERT(code.IsCode()); CodeDescriptor* cd = new CodeDescriptor(AbstractCode(code.raw())); code_objects_.Add(cd); } @@ -1683,11 +1636,6 @@ void ProcessedSample::CheckForMissingDartFrame(const CodeLookupTable& clt, uword pc_marker, uword* stack_buffer) { ASSERT(cd != NULL); - if (cd->code().IsBytecode()) { - // Bytecode frame build is atomic from the profiler's perspective: no - // missing frame. - return; - } const Code& code = Code::Handle(Code::RawCast(cd->code().raw())); ASSERT(!code.IsNull()); // Some stubs (and intrinsics) do not push a frame onto the stack leaving diff --git a/runtime/vm/profiler.h b/runtime/vm/profiler.h index fad8a30cfac..4f92d72ce23 100644 --- a/runtime/vm/profiler.h +++ b/runtime/vm/profiler.h @@ -457,26 +457,20 @@ class NativeAllocationSampleFilter : public SampleFilter { class AbstractCode { public: explicit AbstractCode(ObjectPtr code) : code_(Object::Handle(code)) { - ASSERT(code_.IsNull() || code_.IsCode() || code_.IsBytecode()); + ASSERT(code_.IsNull() || code_.IsCode()); } ObjectPtr raw() const { return code_.raw(); } const Object* handle() const { return &code_; } uword PayloadStart() const { - if (code_.IsCode()) { - return Code::Cast(code_).PayloadStart(); - } else { - return Bytecode::Cast(code_).PayloadStart(); - } + ASSERT(code_.IsCode()); + return Code::Cast(code_).PayloadStart(); } uword Size() const { - if (code_.IsCode()) { - return Code::Cast(code_).Size(); - } else { - return Bytecode::Cast(code_).Size(); - } + ASSERT(code_.IsCode()); + return Code::Cast(code_).Size(); } int64_t compile_timestamp() const { @@ -490,8 +484,6 @@ class AbstractCode { const char* Name() const { if (code_.IsCode()) { return Code::Cast(code_).Name(); - } else if (code_.IsBytecode()) { - return Bytecode::Cast(code_).Name(); } else { return ""; } @@ -501,8 +493,6 @@ class AbstractCode { if (code_.IsCode()) { return Code::Cast(code_).QualifiedName( NameFormattingParams(Object::kUserVisibleName)); - } else if (code_.IsBytecode()) { - return Bytecode::Cast(code_).QualifiedName(); } else { return ""; } @@ -511,8 +501,6 @@ class AbstractCode { bool IsStubCode() const { if (code_.IsCode()) { return Code::Cast(code_).IsStubCode(); - } else if (code_.IsBytecode()) { - return (Bytecode::Cast(code_).function() == Function::null()); } else { return false; } @@ -537,8 +525,6 @@ class AbstractCode { ObjectPtr owner() const { if (code_.IsCode()) { return Code::Cast(code_).owner(); - } else if (code_.IsBytecode()) { - return Bytecode::Cast(code_).function(); } else { return Object::null(); } @@ -546,7 +532,6 @@ class AbstractCode { bool IsNull() const { return code_.IsNull(); } bool IsCode() const { return code_.IsCode(); } - bool IsBytecode() const { return code_.IsBytecode(); } bool is_optimized() const { if (code_.IsCode()) { diff --git a/runtime/vm/profiler_service.cc b/runtime/vm/profiler_service.cc index 3c910490701..4f88ae4ee98 100644 --- a/runtime/vm/profiler_service.cc +++ b/runtime/vm/profiler_service.cc @@ -1218,11 +1218,6 @@ class ProfileBuilder : public ValueObject { (*inlined_token_positions)[i].ToCString()); } } - } else if (profile_code->code().IsBytecode()) { - // No inlining in bytecode. - const Bytecode& bc = Bytecode::CheckedHandle(Thread::Current()->zone(), - profile_code->code().raw()); - token_position = bc.GetTokenIndexOfPC(pc); } if (code.IsNull() || (inlined_functions == NULL) || @@ -1676,11 +1671,6 @@ void Profile::ProcessSampleFrameJSON(JSONArray* stack, (*inlined_token_positions)[i].ToCString()); } } - } else if (profile_code->code().IsBytecode()) { - // No inlining in bytecode. - const Bytecode& bc = Bytecode::CheckedHandle(Thread::Current()->zone(), - profile_code->code().raw()); - token_position = bc.GetTokenIndexOfPC(pc); } if (code.IsNull() || (inlined_functions == NULL) || diff --git a/runtime/vm/profiler_test.cc b/runtime/vm/profiler_test.cc index 1ff4b491eea..6c3589e5cac 100644 --- a/runtime/vm/profiler_test.cc +++ b/runtime/vm/profiler_test.cc @@ -372,11 +372,6 @@ class ProfileStackWalker { inlined_functions_cache_.Get(pc, code, sample_, index_, &inlined_functions_, &inlined_token_positions_, &token_position); - } else if (profile_code->code().IsBytecode()) { - // No inlining in bytecode. - const Bytecode& bc = Bytecode::CheckedHandle(Thread::Current()->zone(), - profile_code->code().raw()); - token_position = bc.GetTokenIndexOfPC(pc); } if (code.IsNull() || (inlined_functions_ == NULL) || @@ -458,23 +453,16 @@ ISOLATE_UNIT_TEST_CASE(Profiler_TrivialRecordAllocation) { // Move down from the root. EXPECT_STREQ("DRT_AllocateObject", walker.VMTagName()); - if (FLAG_enable_interpreter) { - EXPECT_STREQ("[Bytecode] B.boo", walker.CurrentName()); - EXPECT(walker.Down()); - EXPECT_STREQ("[Bytecode] main", walker.CurrentName()); - EXPECT(!walker.Down()); - } else { #if defined(TARGET_ARCH_IA32) // Alloc. stub not impl. for ia32. - EXPECT_STREQ("[Stub] Allocate A", walker.CurrentName()); + EXPECT_STREQ("[Stub] Allocate A", walker.CurrentName()); #else - EXPECT_STREQ("[Stub] AllocateObjectSlow", walker.CurrentName()); + EXPECT_STREQ("[Stub] AllocateObjectSlow", walker.CurrentName()); #endif - EXPECT(walker.Down()); - EXPECT_STREQ("[Unoptimized] B.boo", walker.CurrentName()); - EXPECT(walker.Down()); - EXPECT_STREQ("[Unoptimized] main", walker.CurrentName()); - EXPECT(!walker.Down()); - } + EXPECT(walker.Down()); + EXPECT_STREQ("[Unoptimized] B.boo", walker.CurrentName()); + EXPECT(walker.Down()); + EXPECT_STREQ("[Unoptimized] main", walker.CurrentName()); + EXPECT(!walker.Down()); } // Query with a time filter where no allocations occurred. @@ -658,23 +646,16 @@ ISOLATE_UNIT_TEST_CASE(Profiler_ToggleRecordAllocation) { ProfileStackWalker walker(&profile); EXPECT_STREQ("DRT_AllocateObject", walker.VMTagName()); - if (FLAG_enable_interpreter) { - EXPECT_STREQ("[Bytecode] B.boo", walker.CurrentName()); - EXPECT(walker.Down()); - EXPECT_STREQ("[Bytecode] main", walker.CurrentName()); - EXPECT(!walker.Down()); - } else { #if defined(TARGET_ARCH_IA32) // Alloc. stub not impl. for ia32. - EXPECT_STREQ("[Stub] Allocate A", walker.CurrentName()); + EXPECT_STREQ("[Stub] Allocate A", walker.CurrentName()); #else - EXPECT_STREQ("[Stub] AllocateObjectSlow", walker.CurrentName()); + EXPECT_STREQ("[Stub] AllocateObjectSlow", walker.CurrentName()); #endif - EXPECT(walker.Down()); - EXPECT_STREQ("[Unoptimized] B.boo", walker.CurrentName()); - EXPECT(walker.Down()); - EXPECT_STREQ("[Unoptimized] main", walker.CurrentName()); - EXPECT(!walker.Down()); - } + EXPECT(walker.Down()); + EXPECT_STREQ("[Unoptimized] B.boo", walker.CurrentName()); + EXPECT(walker.Down()); + EXPECT_STREQ("[Unoptimized] main", walker.CurrentName()); + EXPECT(!walker.Down()); } // Turn off allocation tracing for A. @@ -754,30 +735,20 @@ ISOLATE_UNIT_TEST_CASE(Profiler_CodeTicks) { // Move down from the root. EXPECT_STREQ("DRT_AllocateObject", walker.VMTagName()); - if (FLAG_enable_interpreter) { - EXPECT_STREQ("[Bytecode] B.boo", walker.CurrentName()); - EXPECT_EQ(3, walker.CurrentInclusiveTicks()); - EXPECT(walker.Down()); - EXPECT_STREQ("[Bytecode] main", walker.CurrentName()); - EXPECT_EQ(3, walker.CurrentInclusiveTicks()); - EXPECT_EQ(0, walker.CurrentExclusiveTicks()); - EXPECT(!walker.Down()); - } else { #if defined(TARGET_ARCH_IA32) // Alloc. stub not impl. for ia32. - EXPECT_STREQ("[Stub] Allocate A", walker.CurrentName()); + EXPECT_STREQ("[Stub] Allocate A", walker.CurrentName()); #else - EXPECT_STREQ("[Stub] AllocateObjectSlow", walker.CurrentName()); + EXPECT_STREQ("[Stub] AllocateObjectSlow", walker.CurrentName()); #endif - EXPECT_EQ(3, walker.CurrentExclusiveTicks()); - EXPECT(walker.Down()); - EXPECT_STREQ("[Unoptimized] B.boo", walker.CurrentName()); - EXPECT_EQ(3, walker.CurrentInclusiveTicks()); - EXPECT(walker.Down()); - EXPECT_STREQ("[Unoptimized] main", walker.CurrentName()); - EXPECT_EQ(3, walker.CurrentInclusiveTicks()); - EXPECT_EQ(0, walker.CurrentExclusiveTicks()); - EXPECT(!walker.Down()); - } + EXPECT_EQ(3, walker.CurrentExclusiveTicks()); + EXPECT(walker.Down()); + EXPECT_STREQ("[Unoptimized] B.boo", walker.CurrentName()); + EXPECT_EQ(3, walker.CurrentInclusiveTicks()); + EXPECT(walker.Down()); + EXPECT_STREQ("[Unoptimized] main", walker.CurrentName()); + EXPECT_EQ(3, walker.CurrentInclusiveTicks()); + EXPECT_EQ(0, walker.CurrentExclusiveTicks()); + EXPECT(!walker.Down()); } } ISOLATE_UNIT_TEST_CASE(Profiler_FunctionTicks) { @@ -839,15 +810,13 @@ ISOLATE_UNIT_TEST_CASE(Profiler_FunctionTicks) { EXPECT_STREQ("DRT_AllocateObject", walker.VMTagName()); - if (!FLAG_enable_interpreter) { #if defined(TARGET_ARCH_IA32) // Alloc. stub not impl. for ia32. - EXPECT_STREQ("[Stub] Allocate A", walker.CurrentName()); + EXPECT_STREQ("[Stub] Allocate A", walker.CurrentName()); #else - EXPECT_STREQ("[Stub] AllocateObjectSlow", walker.CurrentName()); + EXPECT_STREQ("[Stub] AllocateObjectSlow", walker.CurrentName()); #endif - EXPECT_EQ(3, walker.CurrentExclusiveTicks()); - EXPECT(walker.Down()); - } + EXPECT_EQ(3, walker.CurrentExclusiveTicks()); + EXPECT(walker.Down()); EXPECT_STREQ("B.boo", walker.CurrentName()); EXPECT_EQ(3, walker.CurrentInclusiveTicks()); EXPECT(walker.Down()); @@ -902,19 +871,13 @@ ISOLATE_UNIT_TEST_CASE(Profiler_IntrinsicAllocation) { EXPECT_EQ(1, profile.sample_count()); ProfileStackWalker walker(&profile); - if (FLAG_enable_interpreter) { - EXPECT_STREQ("DRT_AllocateObject", walker.VMTagName()); - EXPECT_STREQ("[Bytecode] foo", walker.CurrentName()); - EXPECT(!walker.Down()); - } else { - EXPECT_STREQ("Double_add", walker.VMTagName()); - EXPECT_STREQ("[Unoptimized] double._add", walker.CurrentName()); - EXPECT(walker.Down()); - EXPECT_STREQ("[Unoptimized] double.+", walker.CurrentName()); - EXPECT(walker.Down()); - EXPECT_STREQ("[Unoptimized] foo", walker.CurrentName()); - EXPECT(!walker.Down()); - } + EXPECT_STREQ("Double_add", walker.VMTagName()); + EXPECT_STREQ("[Unoptimized] double._add", walker.CurrentName()); + EXPECT(walker.Down()); + EXPECT_STREQ("[Unoptimized] double.+", walker.CurrentName()); + EXPECT(walker.Down()); + EXPECT_STREQ("[Unoptimized] foo", walker.CurrentName()); + EXPECT(!walker.Down()); } double_class.SetTraceAllocation(false); @@ -971,19 +934,12 @@ ISOLATE_UNIT_TEST_CASE(Profiler_ArrayAllocation) { ProfileStackWalker walker(&profile); EXPECT_STREQ("DRT_AllocateArray", walker.VMTagName()); - if (FLAG_enable_interpreter) { - EXPECT_STREQ("[Bytecode] new _List", walker.CurrentName()); - EXPECT(walker.Down()); - EXPECT_STREQ("[Bytecode] foo", walker.CurrentName()); - EXPECT(!walker.Down()); - } else { - EXPECT_STREQ("[Stub] AllocateArray", walker.CurrentName()); - EXPECT(walker.Down()); - EXPECT_STREQ("[Unoptimized] new _List", walker.CurrentName()); - EXPECT(walker.Down()); - EXPECT_STREQ("[Unoptimized] foo", walker.CurrentName()); - EXPECT(!walker.Down()); - } + EXPECT_STREQ("[Stub] AllocateArray", walker.CurrentName()); + EXPECT(walker.Down()); + EXPECT_STREQ("[Unoptimized] new _List", walker.CurrentName()); + EXPECT(walker.Down()); + EXPECT_STREQ("[Unoptimized] foo", walker.CurrentName()); + EXPECT(!walker.Down()); } array_class.SetTraceAllocation(false); @@ -1065,15 +1021,10 @@ ISOLATE_UNIT_TEST_CASE(Profiler_ContextAllocation) { ProfileStackWalker walker(&profile); EXPECT_STREQ("DRT_AllocateContext", walker.VMTagName()); - if (FLAG_enable_interpreter) { - EXPECT_STREQ("[Bytecode] foo", walker.CurrentName()); - EXPECT(!walker.Down()); - } else { - EXPECT_STREQ("[Stub] AllocateContext", walker.CurrentName()); - EXPECT(walker.Down()); - EXPECT_STREQ("[Unoptimized] foo", walker.CurrentName()); - EXPECT(!walker.Down()); - } + EXPECT_STREQ("[Stub] AllocateContext", walker.CurrentName()); + EXPECT(walker.Down()); + EXPECT_STREQ("[Unoptimized] foo", walker.CurrentName()); + EXPECT(!walker.Down()); } context_class.SetTraceAllocation(false); @@ -1131,14 +1082,12 @@ ISOLATE_UNIT_TEST_CASE(Profiler_ClosureAllocation) { ProfileStackWalker walker(&profile); EXPECT_SUBSTRING("DRT_AllocateObject", walker.VMTagName()); - if (!FLAG_enable_interpreter) { #if defined(TARGET_ARCH_IA32) // Alloc. stub not impl. for ia32. - EXPECT_STREQ("[Stub] Allocate _Closure", walker.CurrentName()); + EXPECT_STREQ("[Stub] Allocate _Closure", walker.CurrentName()); #else - EXPECT_STREQ("[Stub] AllocateObjectSlow", walker.CurrentName()); + EXPECT_STREQ("[Stub] AllocateObjectSlow", walker.CurrentName()); #endif - EXPECT(walker.Down()); - } + EXPECT(walker.Down()); EXPECT_SUBSTRING("foo", walker.CurrentName()); EXPECT(!walker.Down()); } @@ -1204,19 +1153,12 @@ ISOLATE_UNIT_TEST_CASE(Profiler_TypedArrayAllocation) { ProfileStackWalker walker(&profile); EXPECT_STREQ("DRT_AllocateTypedData", walker.VMTagName()); - if (FLAG_enable_interpreter) { - EXPECT_STREQ("[Bytecode] new Float32List", walker.CurrentName()); - EXPECT(walker.Down()); - EXPECT_STREQ("[Bytecode] foo", walker.CurrentName()); - EXPECT(!walker.Down()); - } else { - EXPECT_STREQ("[Stub] AllocateFloat32Array", walker.CurrentName()); - EXPECT(walker.Down()); - EXPECT_STREQ("[Unoptimized] new Float32List", walker.CurrentName()); - EXPECT(walker.Down()); - EXPECT_STREQ("[Unoptimized] foo", walker.CurrentName()); - EXPECT(!walker.Down()); - } + EXPECT_STREQ("[Stub] AllocateFloat32Array", walker.CurrentName()); + EXPECT(walker.Down()); + EXPECT_STREQ("[Unoptimized] new Float32List", walker.CurrentName()); + EXPECT(walker.Down()); + EXPECT_STREQ("[Unoptimized] foo", walker.CurrentName()); + EXPECT(!walker.Down()); } float32_list_class.SetTraceAllocation(false); @@ -1291,17 +1233,10 @@ ISOLATE_UNIT_TEST_CASE(Profiler_StringAllocation) { ProfileStackWalker walker(&profile); EXPECT_STREQ("String_concat", walker.VMTagName()); - if (FLAG_enable_interpreter) { - EXPECT_STREQ("[Bytecode] _StringBase.+", walker.CurrentName()); - EXPECT(walker.Down()); - EXPECT_STREQ("[Bytecode] foo", walker.CurrentName()); - EXPECT(!walker.Down()); - } else { - EXPECT_STREQ("[Unoptimized] _StringBase.+", walker.CurrentName()); - EXPECT(walker.Down()); - EXPECT_STREQ("[Unoptimized] foo", walker.CurrentName()); - EXPECT(!walker.Down()); - } + EXPECT_STREQ("[Unoptimized] _StringBase.+", walker.CurrentName()); + EXPECT(walker.Down()); + EXPECT_STREQ("[Unoptimized] foo", walker.CurrentName()); + EXPECT(!walker.Down()); } one_byte_string_class.SetTraceAllocation(false); @@ -1376,31 +1311,16 @@ ISOLATE_UNIT_TEST_CASE(Profiler_StringInterpolation) { ProfileStackWalker walker(&profile); EXPECT_STREQ("Internal_allocateOneByteString", walker.VMTagName()); - if (FLAG_enable_interpreter) { - EXPECT_STREQ("Internal_allocateOneByteString", walker.VMTagName()); - EXPECT(walker.Down()); - EXPECT_STREQ("[Unoptimized] String._allocate", walker.CurrentName()); - EXPECT(walker.Down()); - EXPECT_STREQ("[Unoptimized] String._concatAll", walker.CurrentName()); - EXPECT(walker.Down()); - EXPECT_STREQ("[Unoptimized] _StringBase._interpolate", - walker.CurrentName()); - EXPECT(walker.Down()); - EXPECT_STREQ("[Bytecode] foo", walker.CurrentName()); - EXPECT(!walker.Down()); - } else { - EXPECT_STREQ("Internal_allocateOneByteString", walker.VMTagName()); - EXPECT(walker.Down()); - EXPECT_STREQ("[Unoptimized] String._allocate", walker.CurrentName()); - EXPECT(walker.Down()); - EXPECT_STREQ("[Unoptimized] String._concatAll", walker.CurrentName()); - EXPECT(walker.Down()); - EXPECT_STREQ("[Unoptimized] _StringBase._interpolate", - walker.CurrentName()); - EXPECT(walker.Down()); - EXPECT_STREQ("[Unoptimized] foo", walker.CurrentName()); - EXPECT(!walker.Down()); - } + EXPECT(walker.Down()); + EXPECT_STREQ("[Unoptimized] String._allocate", walker.CurrentName()); + EXPECT(walker.Down()); + EXPECT_STREQ("[Unoptimized] String._concatAll", walker.CurrentName()); + EXPECT(walker.Down()); + EXPECT_STREQ("[Unoptimized] _StringBase._interpolate", + walker.CurrentName()); + EXPECT(walker.Down()); + EXPECT_STREQ("[Unoptimized] foo", walker.CurrentName()); + EXPECT(!walker.Down()); } one_byte_string_class.SetTraceAllocation(false); @@ -1435,7 +1355,6 @@ ISOLATE_UNIT_TEST_CASE(Profiler_FunctionInline) { DisableNativeProfileScope dnps; DisableBackgroundCompilationScope dbcs; SetFlagScope sfs(&FLAG_optimization_counter_threshold, 30000); - SetFlagScope sfs2(&FLAG_compilation_counter_threshold, 0); const char* kScript = "class A {\n" @@ -1562,7 +1481,6 @@ ISOLATE_UNIT_TEST_CASE(Profiler_InliningIntervalBoundry) { DisableNativeProfileScope dnps; DisableBackgroundCompilationScope dbcs; SetFlagScope sfs(&FLAG_optimization_counter_threshold, 30000); - SetFlagScope sfs2(&FLAG_compilation_counter_threshold, 0); const char* kScript = "class A {\n" @@ -1728,95 +1646,52 @@ ISOLATE_UNIT_TEST_CASE(Profiler_ChainedSamples) { ProfileStackWalker walker(&profile); EXPECT_STREQ("DRT_AllocateObject", walker.VMTagName()); - if (FLAG_enable_interpreter) { - EXPECT_STREQ("[Bytecode] B.boo", walker.CurrentName()); - EXPECT(walker.Down()); - EXPECT_STREQ("[Bytecode] orange", walker.CurrentName()); - EXPECT(walker.Down()); - EXPECT_STREQ("[Bytecode] napkin", walker.CurrentName()); - EXPECT(walker.Down()); - EXPECT_STREQ("[Bytecode] mayo", walker.CurrentName()); - EXPECT(walker.Down()); - EXPECT_STREQ("[Bytecode] lemon", walker.CurrentName()); - EXPECT(walker.Down()); - EXPECT_STREQ("[Bytecode] kindle", walker.CurrentName()); - EXPECT(walker.Down()); - EXPECT_STREQ("[Bytecode] jeep", walker.CurrentName()); - EXPECT(walker.Down()); - EXPECT_STREQ("[Bytecode] ice", walker.CurrentName()); - EXPECT(walker.Down()); - EXPECT_STREQ("[Bytecode] haystack", walker.CurrentName()); - EXPECT(walker.Down()); - EXPECT_STREQ("[Bytecode] granola", walker.CurrentName()); - EXPECT(walker.Down()); - EXPECT_STREQ("[Bytecode] fred", walker.CurrentName()); - EXPECT(walker.Down()); - EXPECT_STREQ("[Bytecode] elephant", walker.CurrentName()); - EXPECT(walker.Down()); - EXPECT_STREQ("[Bytecode] dog", walker.CurrentName()); - EXPECT(walker.Down()); - EXPECT_STREQ("[Bytecode] cantaloupe", walker.CurrentName()); - EXPECT(walker.Down()); - EXPECT_STREQ("[Bytecode] banana", walker.CurrentName()); - EXPECT(walker.Down()); - EXPECT_STREQ("[Bytecode] apple", walker.CurrentName()); - EXPECT(walker.Down()); - EXPECT_STREQ("[Bytecode] secondInit", walker.CurrentName()); - EXPECT(walker.Down()); - EXPECT_STREQ("[Bytecode] init", walker.CurrentName()); - EXPECT(walker.Down()); - EXPECT_STREQ("[Bytecode] go", walker.CurrentName()); - EXPECT(walker.Down()); - EXPECT_STREQ("[Bytecode] main", walker.CurrentName()); - EXPECT(!walker.Down()); - } else { #if defined(TARGET_ARCH_IA32) // Alloc. stub not impl. for ia32. - EXPECT_STREQ("[Stub] Allocate A", walker.CurrentName()); + EXPECT_STREQ("[Stub] Allocate A", walker.CurrentName()); #else - EXPECT_STREQ("[Stub] AllocateObjectSlow", walker.CurrentName()); + EXPECT_STREQ("[Stub] AllocateObjectSlow", walker.CurrentName()); #endif - EXPECT(walker.Down()); - EXPECT_STREQ("[Unoptimized] B.boo", walker.CurrentName()); - EXPECT(walker.Down()); - EXPECT_STREQ("[Unoptimized] orange", walker.CurrentName()); - EXPECT(walker.Down()); - EXPECT_STREQ("[Unoptimized] napkin", walker.CurrentName()); - EXPECT(walker.Down()); - EXPECT_STREQ("[Unoptimized] mayo", walker.CurrentName()); - EXPECT(walker.Down()); - EXPECT_STREQ("[Unoptimized] lemon", walker.CurrentName()); - EXPECT(walker.Down()); - EXPECT_STREQ("[Unoptimized] kindle", walker.CurrentName()); - EXPECT(walker.Down()); - EXPECT_STREQ("[Unoptimized] jeep", walker.CurrentName()); - EXPECT(walker.Down()); - EXPECT_STREQ("[Unoptimized] ice", walker.CurrentName()); - EXPECT(walker.Down()); - EXPECT_STREQ("[Unoptimized] haystack", walker.CurrentName()); - EXPECT(walker.Down()); - EXPECT_STREQ("[Unoptimized] granola", walker.CurrentName()); - EXPECT(walker.Down()); - EXPECT_STREQ("[Unoptimized] fred", walker.CurrentName()); - EXPECT(walker.Down()); - EXPECT_STREQ("[Unoptimized] elephant", walker.CurrentName()); - EXPECT(walker.Down()); - EXPECT_STREQ("[Unoptimized] dog", walker.CurrentName()); - EXPECT(walker.Down()); - EXPECT_STREQ("[Unoptimized] cantaloupe", walker.CurrentName()); - EXPECT(walker.Down()); - EXPECT_STREQ("[Unoptimized] banana", walker.CurrentName()); - EXPECT(walker.Down()); - EXPECT_STREQ("[Unoptimized] apple", walker.CurrentName()); - EXPECT(walker.Down()); - EXPECT_STREQ("[Unoptimized] secondInit", walker.CurrentName()); - EXPECT(walker.Down()); - EXPECT_STREQ("[Unoptimized] init", walker.CurrentName()); - EXPECT(walker.Down()); - EXPECT_STREQ("[Unoptimized] go", walker.CurrentName()); - EXPECT(walker.Down()); - EXPECT_STREQ("[Unoptimized] main", walker.CurrentName()); - EXPECT(!walker.Down()); - } + EXPECT(walker.Down()); + EXPECT_STREQ("[Unoptimized] B.boo", walker.CurrentName()); + EXPECT(walker.Down()); + EXPECT_STREQ("[Unoptimized] orange", walker.CurrentName()); + EXPECT(walker.Down()); + EXPECT_STREQ("[Unoptimized] napkin", walker.CurrentName()); + EXPECT(walker.Down()); + EXPECT_STREQ("[Unoptimized] mayo", walker.CurrentName()); + EXPECT(walker.Down()); + EXPECT_STREQ("[Unoptimized] lemon", walker.CurrentName()); + EXPECT(walker.Down()); + EXPECT_STREQ("[Unoptimized] kindle", walker.CurrentName()); + EXPECT(walker.Down()); + EXPECT_STREQ("[Unoptimized] jeep", walker.CurrentName()); + EXPECT(walker.Down()); + EXPECT_STREQ("[Unoptimized] ice", walker.CurrentName()); + EXPECT(walker.Down()); + EXPECT_STREQ("[Unoptimized] haystack", walker.CurrentName()); + EXPECT(walker.Down()); + EXPECT_STREQ("[Unoptimized] granola", walker.CurrentName()); + EXPECT(walker.Down()); + EXPECT_STREQ("[Unoptimized] fred", walker.CurrentName()); + EXPECT(walker.Down()); + EXPECT_STREQ("[Unoptimized] elephant", walker.CurrentName()); + EXPECT(walker.Down()); + EXPECT_STREQ("[Unoptimized] dog", walker.CurrentName()); + EXPECT(walker.Down()); + EXPECT_STREQ("[Unoptimized] cantaloupe", walker.CurrentName()); + EXPECT(walker.Down()); + EXPECT_STREQ("[Unoptimized] banana", walker.CurrentName()); + EXPECT(walker.Down()); + EXPECT_STREQ("[Unoptimized] apple", walker.CurrentName()); + EXPECT(walker.Down()); + EXPECT_STREQ("[Unoptimized] secondInit", walker.CurrentName()); + EXPECT(walker.Down()); + EXPECT_STREQ("[Unoptimized] init", walker.CurrentName()); + EXPECT(walker.Down()); + EXPECT_STREQ("[Unoptimized] go", walker.CurrentName()); + EXPECT(walker.Down()); + EXPECT_STREQ("[Unoptimized] main", walker.CurrentName()); + EXPECT(!walker.Down()); } } @@ -1866,15 +1741,13 @@ ISOLATE_UNIT_TEST_CASE(Profiler_BasicSourcePosition) { ProfileStackWalker walker(&profile, true); EXPECT_STREQ("DRT_AllocateObject", walker.VMTagName()); - if (!FLAG_enable_interpreter) { #if defined(TARGET_ARCH_IA32) // Alloc. stub not impl. for ia32. - EXPECT_STREQ("[Stub] Allocate A", walker.CurrentName()); + EXPECT_STREQ("[Stub] Allocate A", walker.CurrentName()); #else - EXPECT_STREQ("[Stub] AllocateObjectSlow", walker.CurrentName()); + EXPECT_STREQ("[Stub] AllocateObjectSlow", walker.CurrentName()); #endif - EXPECT_EQ(1, walker.CurrentExclusiveTicks()); - EXPECT(walker.Down()); - } + EXPECT_EQ(1, walker.CurrentExclusiveTicks()); + EXPECT(walker.Down()); EXPECT_STREQ("B.boo", walker.CurrentName()); EXPECT_EQ(1, walker.CurrentInclusiveTicks()); EXPECT_STREQ("A", walker.CurrentToken()); @@ -1893,7 +1766,6 @@ ISOLATE_UNIT_TEST_CASE(Profiler_BasicSourcePositionOptimized) { DisableBackgroundCompilationScope dbcs; // Optimize quickly. SetFlagScope sfs(&FLAG_optimization_counter_threshold, 5); - SetFlagScope sfs2(&FLAG_compilation_counter_threshold, 0); const char* kScript = "class A {\n" " var a;\n" @@ -2029,15 +1901,13 @@ ISOLATE_UNIT_TEST_CASE(Profiler_SourcePosition) { ProfileStackWalker walker(&profile, true); EXPECT_STREQ("DRT_AllocateObject", walker.VMTagName()); - if (!FLAG_enable_interpreter) { #if defined(TARGET_ARCH_IA32) // Alloc. stub not impl. for ia32. - EXPECT_STREQ("[Stub] Allocate A", walker.CurrentName()); + EXPECT_STREQ("[Stub] Allocate A", walker.CurrentName()); #else - EXPECT_STREQ("[Stub] AllocateObjectSlow", walker.CurrentName()); + EXPECT_STREQ("[Stub] AllocateObjectSlow", walker.CurrentName()); #endif - EXPECT_EQ(1, walker.CurrentExclusiveTicks()); - EXPECT(walker.Down()); - } + EXPECT_EQ(1, walker.CurrentExclusiveTicks()); + EXPECT(walker.Down()); EXPECT_STREQ("B.boo", walker.CurrentName()); EXPECT_EQ(1, walker.CurrentInclusiveTicks()); EXPECT_STREQ("A", walker.CurrentToken()); @@ -2071,7 +1941,6 @@ ISOLATE_UNIT_TEST_CASE(Profiler_SourcePositionOptimized) { DisableBackgroundCompilationScope dbcs; // Optimize quickly. SetFlagScope sfs(&FLAG_optimization_counter_threshold, 5); - SetFlagScope sfs2(&FLAG_compilation_counter_threshold, 0); const char* kScript = "class A {\n" @@ -2237,15 +2106,13 @@ ISOLATE_UNIT_TEST_CASE(Profiler_BinaryOperatorSourcePosition) { ProfileStackWalker walker(&profile, true); EXPECT_STREQ("DRT_AllocateObject", walker.VMTagName()); - if (!FLAG_enable_interpreter) { #if defined(TARGET_ARCH_IA32) // Alloc. stub not impl. for ia32. - EXPECT_STREQ("[Stub] Allocate A", walker.CurrentName()); + EXPECT_STREQ("[Stub] Allocate A", walker.CurrentName()); #else - EXPECT_STREQ("[Stub] AllocateObjectSlow", walker.CurrentName()); + EXPECT_STREQ("[Stub] AllocateObjectSlow", walker.CurrentName()); #endif - EXPECT_EQ(1, walker.CurrentExclusiveTicks()); - EXPECT(walker.Down()); - } + EXPECT_EQ(1, walker.CurrentExclusiveTicks()); + EXPECT(walker.Down()); EXPECT_STREQ("B.boo", walker.CurrentName()); EXPECT_EQ(1, walker.CurrentInclusiveTicks()); EXPECT_STREQ("A", walker.CurrentToken()); @@ -2284,7 +2151,6 @@ ISOLATE_UNIT_TEST_CASE(Profiler_BinaryOperatorSourcePositionOptimized) { DisableBackgroundCompilationScope dbcs; // Optimize quickly. SetFlagScope sfs(&FLAG_optimization_counter_threshold, 5); - SetFlagScope sfs2(&FLAG_compilation_counter_threshold, 0); const char* kScript = "class A {\n" diff --git a/runtime/vm/program_visitor.cc b/runtime/vm/program_visitor.cc index a0917e3aa53..5b7319c6222 100644 --- a/runtime/vm/program_visitor.cc +++ b/runtime/vm/program_visitor.cc @@ -749,7 +749,6 @@ void ProgramVisitor::DedupPcDescriptors(Zone* zone, Isolate* isolate) { public: explicit DedupPcDescriptorsVisitor(Zone* zone) : Dedupper(zone), - bytecode_(Bytecode::Handle(zone)), pc_descriptor_(PcDescriptors::Handle(zone)) { if (Snapshot::IncludesCode(Dart::vm_snapshot_kind())) { // Prefer existing objects in the VM isolate. @@ -763,17 +762,7 @@ void ProgramVisitor::DedupPcDescriptors(Zone* zone, Isolate* isolate) { code.set_pc_descriptors(pc_descriptor_); } - void VisitFunction(const Function& function) { - bytecode_ = function.bytecode(); - if (bytecode_.IsNull()) return; - if (bytecode_.InVMIsolateHeap()) return; - pc_descriptor_ = bytecode_.pc_descriptors(); - pc_descriptor_ = Dedup(pc_descriptor_); - bytecode_.set_pc_descriptors(pc_descriptor_); - } - private: - Bytecode& bytecode_; PcDescriptors& pc_descriptor_; }; diff --git a/runtime/vm/raw_object.cc b/runtime/vm/raw_object.cc index 3dfd910f058..1feb3301fc1 100644 --- a/runtime/vm/raw_object.cc +++ b/runtime/vm/raw_object.cc @@ -505,7 +505,6 @@ bool ObjectLayout::FindObject(FindObjectVisitor* visitor) { } REGULAR_VISITOR(Class) -REGULAR_VISITOR(Bytecode) REGULAR_VISITOR(Type) REGULAR_VISITOR(TypeRef) REGULAR_VISITOR(TypeParameter) @@ -520,7 +519,6 @@ REGULAR_VISITOR(Script) REGULAR_VISITOR(Library) REGULAR_VISITOR(LibraryPrefix) REGULAR_VISITOR(Namespace) -REGULAR_VISITOR(ParameterTypeCheck) REGULAR_VISITOR(SingleTargetCache) REGULAR_VISITOR(UnlinkedCall) REGULAR_VISITOR(MonomorphicSmiableCall) @@ -645,16 +643,6 @@ intptr_t CodeLayout::VisitCodePointers(CodePtr raw_obj, #endif } -bool BytecodeLayout::ContainsPC(ObjectPtr raw_obj, uword pc) { - if (raw_obj->IsBytecode()) { - BytecodePtr raw_bytecode = static_cast(raw_obj); - uword start = raw_bytecode->ptr()->instructions_; - uword size = raw_bytecode->ptr()->instructions_size_; - return (pc - start) <= size; // pc may point past last instruction. - } - return false; -} - intptr_t ObjectPoolLayout::VisitObjectPoolPointers( ObjectPoolPtr raw_obj, ObjectPointerVisitor* visitor) { @@ -664,8 +652,7 @@ intptr_t ObjectPoolLayout::VisitObjectPoolPointers( for (intptr_t i = 0; i < length; ++i) { ObjectPool::EntryType entry_type = ObjectPool::TypeBits::decode(entry_bits[i]); - if ((entry_type == ObjectPool::EntryType::kTaggedObject) || - (entry_type == ObjectPool::EntryType::kNativeEntryData)) { + if (entry_type == ObjectPool::EntryType::kTaggedObject) { visitor->VisitPointer(&entries[i].raw_obj_); } } diff --git a/runtime/vm/raw_object.h b/runtime/vm/raw_object.h index 00f48607987..4a713b60614 100644 --- a/runtime/vm/raw_object.h +++ b/runtime/vm/raw_object.h @@ -92,8 +92,6 @@ enum TypedDataElementType { friend class object; \ friend class ObjectLayout; \ friend class Heap; \ - friend class Interpreter; \ - friend class InterpreterHelpers; \ friend class Simulator; \ friend class SimulatorHelpers; \ friend class OffsetsTable; \ @@ -694,8 +692,6 @@ class ObjectLayout { friend class Instance; // StorePointer friend class StackFrame; // GetCodeObject assertion. friend class CodeLookupTableBuilder; // profiler - friend class Interpreter; - friend class InterpreterHelpers; friend class Simulator; friend class SimulatorHelpers; friend class ObjectLocator; @@ -804,9 +800,7 @@ class ClassLayout : public ObjectLayout { #endif // !defined(DART_PRECOMPILED_RUNTIME) #if !defined(DART_PRECOMPILED_RUNTIME) - typedef BitField IsDeclaredInBytecode; - typedef BitField BinaryDeclarationOffset; - uint32_t binary_declaration_; + uint32_t kernel_offset_; #endif // !defined(DART_PRECOMPILED_RUNTIME) friend class Instance; @@ -943,7 +937,7 @@ class FunctionLayout : public ObjectLayout { // an integer or a double. It includes the two bits for the receiver, even // though currently we do not have information from TFA that allows the // receiver to be unboxed. - class UnboxedParameterBitmap { + class alignas(8) UnboxedParameterBitmap { public: static constexpr intptr_t kBitsPerParameter = 2; static constexpr intptr_t kParameterBitmask = (1 << kBitsPerParameter) - 1; @@ -1044,7 +1038,6 @@ class FunctionLayout : public ObjectLayout { return reinterpret_cast(&ic_data_array_); } CodePtr code_; // Currently active code. Accessed from generated code. - NOT_IN_PRECOMPILED(BytecodePtr bytecode_); NOT_IN_PRECOMPILED(CodePtr unoptimized_code_); // Unoptimized code, keep it // after optimization. #if defined(DART_PRECOMPILED_RUNTIME) @@ -1053,6 +1046,7 @@ class FunctionLayout : public ObjectLayout { VISIT_TO(ObjectPtr, unoptimized_code_); #endif + NOT_IN_PRECOMPILED(UnboxedParameterBitmap unboxed_parameters_info_); NOT_IN_PRECOMPILED(TokenPosition token_pos_); NOT_IN_PRECOMPILED(TokenPosition end_token_pos_); uint32_t kind_tag_; // See Function::KindTagBits. @@ -1093,17 +1087,13 @@ class FunctionLayout : public ObjectLayout { F(int, int8_t, inlining_depth) #if !defined(DART_PRECOMPILED_RUNTIME) - typedef BitField IsDeclaredInBytecode; - typedef BitField BinaryDeclarationOffset; - uint32_t binary_declaration_; + uint32_t kernel_offset_; #define DECLARE(return_type, type, name) type name##_; JIT_FUNCTION_COUNTERS(DECLARE) #undef DECLARE #endif // !defined(DART_PRECOMPILED_RUNTIME) - - NOT_IN_PRECOMPILED(UnboxedParameterBitmap unboxed_parameters_info_); }; class ClosureDataLayout : public ObjectLayout { @@ -1226,9 +1216,7 @@ class FieldLayout : public ObjectLayout { // kInvalidCid otherwise. #if !defined(DART_PRECOMPILED_RUNTIME) - typedef BitField IsDeclaredInBytecode; - typedef BitField BinaryDeclarationOffset; - uint32_t binary_declaration_; + uint32_t kernel_offset_; #endif // !defined(DART_PRECOMPILED_RUNTIME) // Offset to the guarded length field inside an instance of class matching @@ -1376,9 +1364,7 @@ class LibraryLayout : public ObjectLayout { uint8_t flags_; // BitField for LibraryFlags. #if !defined(DART_PRECOMPILED_RUNTIME) - typedef BitField IsDeclaredInBytecode; - typedef BitField BinaryDeclarationOffset; - uint32_t binary_declaration_; + uint32_t kernel_offset_; #endif // !defined(DART_PRECOMPILED_RUNTIME) friend class Class; @@ -1409,7 +1395,6 @@ class KernelProgramInfoLayout : public ObjectLayout { ExternalTypedDataPtr metadata_mappings_; ArrayPtr scripts_; ArrayPtr constants_; - ArrayPtr bytecode_component_; GrowableObjectArrayPtr potential_natives_; GrowableObjectArrayPtr potential_pragma_functions_; ExternalTypedDataPtr constants_table_; @@ -1553,39 +1538,6 @@ class CodeLayout : public ObjectLayout { friend class CallSiteResetter; }; -class BytecodeLayout : public ObjectLayout { - RAW_HEAP_OBJECT_IMPLEMENTATION(Bytecode); - - uword instructions_; - intptr_t instructions_size_; - - VISIT_FROM(ObjectPtr, object_pool_); - ObjectPoolPtr object_pool_; - FunctionPtr function_; - ArrayPtr closures_; - ExceptionHandlersPtr exception_handlers_; - PcDescriptorsPtr pc_descriptors_; - NOT_IN_PRODUCT(LocalVarDescriptorsPtr var_descriptors_); -#if defined(PRODUCT) - VISIT_TO(ObjectPtr, pc_descriptors_); -#else - VISIT_TO(ObjectPtr, var_descriptors_); -#endif - - ObjectPtr* to_snapshot(Snapshot::Kind kind) { - return reinterpret_cast(&pc_descriptors_); - } - - int32_t instructions_binary_offset_; - int32_t source_positions_binary_offset_; - int32_t local_variables_binary_offset_; - - static bool ContainsPC(ObjectPtr raw_obj, uword pc); - - friend class Function; - friend class StackFrame; -}; - class ObjectPoolLayout : public ObjectLayout { RAW_HEAP_OBJECT_IMPLEMENTATION(ObjectPool); @@ -2014,18 +1966,6 @@ class ContextScopeLayout : public ObjectLayout { friend class SnapshotReader; }; -class ParameterTypeCheckLayout : public ObjectLayout { - RAW_HEAP_OBJECT_IMPLEMENTATION(ParameterTypeCheck); - intptr_t index_; - VISIT_FROM(ObjectPtr, param_); - AbstractTypePtr param_; - AbstractTypePtr type_or_bound_; - StringPtr name_; - SubtypeTestCachePtr cache_; - VISIT_TO(ObjectPtr, cache_); - ObjectPtr* to_snapshot(Snapshot::Kind kind) { return to(); } -}; - class SingleTargetCacheLayout : public ObjectLayout { RAW_HEAP_OBJECT_IMPLEMENTATION(SingleTargetCache); VISIT_FROM(ObjectPtr, target_); @@ -2744,8 +2684,6 @@ class ExternalTypedDataLayout : public TypedDataBaseLayout { protected: VISIT_FROM(RawCompressed, length_) VISIT_TO(RawCompressed, length_) - - friend class BytecodeLayout; }; class PointerLayout : public PointerBaseLayout { diff --git a/runtime/vm/raw_object_fields.cc b/runtime/vm/raw_object_fields.cc index 8b6b1848172..7276a2512b0 100644 --- a/runtime/vm/raw_object_fields.cc +++ b/runtime/vm/raw_object_fields.cc @@ -89,7 +89,6 @@ namespace dart { F(KernelProgramInfo, metadata_mappings_) \ F(KernelProgramInfo, scripts_) \ F(KernelProgramInfo, constants_) \ - F(KernelProgramInfo, bytecode_component_) \ F(KernelProgramInfo, potential_natives_) \ F(KernelProgramInfo, potential_pragma_functions_) \ F(KernelProgramInfo, constants_table_) \ @@ -105,18 +104,8 @@ namespace dart { F(Code, compressed_stackmaps_) \ F(Code, inlined_id_to_function_) \ F(Code, code_source_map_) \ - F(Bytecode, object_pool_) \ - F(Bytecode, instructions_) \ - F(Bytecode, function_) \ - F(Bytecode, exception_handlers_) \ - F(Bytecode, pc_descriptors_) \ - F(Bytecode, closures_) \ F(ExceptionHandlers, handled_types_data_) \ F(Context, parent_) \ - F(ParameterTypeCheck, param_) \ - F(ParameterTypeCheck, type_or_bound_) \ - F(ParameterTypeCheck, name_) \ - F(ParameterTypeCheck, cache_) \ F(SingleTargetCache, target_) \ F(UnlinkedCall, target_name_) \ F(UnlinkedCall, args_descriptor_) \ @@ -215,7 +204,6 @@ namespace dart { F(Code, deopt_info_array_) \ F(Code, static_calls_target_table_) \ F(ICData, receivers_static_type_) \ - F(Function, bytecode_) \ F(Function, unoptimized_code_) \ F(Field, saved_initial_value_) \ F(Field, type_test_cache_) \ diff --git a/runtime/vm/raw_object_snapshot.cc b/runtime/vm/raw_object_snapshot.cc index 2f36c97dd05..0ec7de38976 100644 --- a/runtime/vm/raw_object_snapshot.cc +++ b/runtime/vm/raw_object_snapshot.cc @@ -545,7 +545,6 @@ void ContextScopeLayout::WriteTo(SnapshotWriter* writer, MESSAGE_SNAPSHOT_UNREACHABLE(AbstractType); MESSAGE_SNAPSHOT_UNREACHABLE(Bool); -MESSAGE_SNAPSHOT_UNREACHABLE(Bytecode); MESSAGE_SNAPSHOT_UNREACHABLE(ClosureData); MESSAGE_SNAPSHOT_UNREACHABLE(Code); MESSAGE_SNAPSHOT_UNREACHABLE(CodeSourceMap); @@ -566,7 +565,6 @@ MESSAGE_SNAPSHOT_UNREACHABLE(LocalVarDescriptors); MESSAGE_SNAPSHOT_UNREACHABLE(MegamorphicCache); MESSAGE_SNAPSHOT_UNREACHABLE(Namespace); MESSAGE_SNAPSHOT_UNREACHABLE(ObjectPool); -MESSAGE_SNAPSHOT_UNREACHABLE(ParameterTypeCheck); MESSAGE_SNAPSHOT_UNREACHABLE(PatchClass); MESSAGE_SNAPSHOT_UNREACHABLE(PcDescriptors); MESSAGE_SNAPSHOT_UNREACHABLE(RedirectionData); diff --git a/runtime/vm/reusable_handles.h b/runtime/vm/reusable_handles.h index 2c06da9f9d2..7c452bc3d5c 100644 --- a/runtime/vm/reusable_handles.h +++ b/runtime/vm/reusable_handles.h @@ -86,8 +86,6 @@ REUSABLE_HANDLE_LIST(REUSABLE_SCOPE) ReusableClassHandleScope reused_class_handle(thread); #define REUSABLE_CODE_HANDLESCOPE(thread) \ ReusableCodeHandleScope reused_code_handle(thread); -#define REUSABLE_BYTECODE_HANDLESCOPE(thread) \ - ReusableBytecodeHandleScope reused_bytecode_handle(thread); #define REUSABLE_ERROR_HANDLESCOPE(thread) \ ReusableErrorHandleScope reused_error_handle(thread); #define REUSABLE_EXCEPTION_HANDLERS_HANDLESCOPE(thread) \ diff --git a/runtime/vm/runtime_entry.cc b/runtime/vm/runtime_entry.cc index 4219416f747..0b4ceb7652c 100644 --- a/runtime/vm/runtime_entry.cc +++ b/runtime/vm/runtime_entry.cc @@ -17,7 +17,6 @@ #include "vm/flags.h" #include "vm/heap/verifier.h" #include "vm/instructions.h" -#include "vm/interpreter.h" #include "vm/kernel_isolate.h" #include "vm/message.h" #include "vm/message_handler.h" @@ -61,7 +60,6 @@ DEFINE_FLAG(bool, false, "Trace deoptimization verbose"); -DECLARE_FLAG(bool, enable_interpreter); DECLARE_FLAG(int, max_deoptimization_counter_threshold); DECLARE_FLAG(bool, trace_compiler); DECLARE_FLAG(bool, trace_optimizing_compiler); @@ -179,7 +177,6 @@ DEFINE_RUNTIME_ENTRY(NullError, 0) { StackFrameIterator::kNoCrossThreadIteration); const StackFrame* caller_frame = iterator.NextFrame(); ASSERT(caller_frame->IsDartFrame()); - ASSERT(!caller_frame->is_interpreted()); const Code& code = Code::Handle(zone, caller_frame->LookupDartCode()); const uword pc_offset = caller_frame->pc() - code.PayloadStart(); @@ -496,13 +493,6 @@ DEFINE_RUNTIME_ENTRY(SubtypeCheck, 5) { UNREACHABLE(); } -// Allocate a new SubtypeTestCache for use in interpreted implicit setters. -// Return value: newly allocated SubtypeTestCache. -DEFINE_RUNTIME_ENTRY(AllocateSubtypeTestCache, 0) { - ASSERT(FLAG_enable_interpreter); - arguments.SetReturn(SubtypeTestCache::Handle(zone, SubtypeTestCache::New())); -} - // Allocate a new context large enough to hold the given number of variables. // Arg0: number of variables. // Return value: newly allocated context. @@ -530,76 +520,6 @@ DEFINE_RUNTIME_ENTRY(CloneContext, 1) { arguments.SetReturn(cloned_ctx); } -// Invoke field getter before dispatch. -// Arg0: instance. -// Arg1: field name (may be demangled during call). -// Return value: field value. -DEFINE_RUNTIME_ENTRY(GetFieldForDispatch, 2) { - ASSERT(FLAG_enable_interpreter); - const Instance& receiver = Instance::CheckedHandle(zone, arguments.ArgAt(0)); - String& name = String::CheckedHandle(zone, arguments.ArgAt(1)); - const Class& receiver_class = Class::Handle(zone, receiver.clazz()); - if (Function::IsDynamicInvocationForwarderName(name)) { - name = Function::DemangleDynamicInvocationForwarderName(name); - arguments.SetArgAt(1, name); // Reflect change in arguments. - } - const String& getter_name = String::Handle(zone, Field::GetterName(name)); - const int kTypeArgsLen = 0; - const int kNumArguments = 1; - ArgumentsDescriptor args_desc(Array::Handle( - zone, ArgumentsDescriptor::NewBoxed(kTypeArgsLen, kNumArguments))); - const Function& getter = - Function::Handle(zone, Resolver::ResolveDynamicForReceiverClass( - receiver_class, getter_name, args_desc)); - ASSERT(!getter.IsNull()); // An InvokeFieldDispatcher function was created. - const Array& args = Array::Handle(zone, Array::New(kNumArguments)); - args.SetAt(0, receiver); - const Object& result = - Object::Handle(zone, DartEntry::InvokeFunction(getter, args)); - ThrowIfError(result); - arguments.SetReturn(result); -} - -// Check that arguments are valid for the given closure. -// Arg0: closure -// Arg1: arguments descriptor -// Return value: whether the arguments are valid -DEFINE_RUNTIME_ENTRY(ClosureArgumentsValid, 2) { - ASSERT(FLAG_enable_interpreter); - const auto& closure = Closure::CheckedHandle(zone, arguments.ArgAt(0)); - const auto& descriptor = Array::CheckedHandle(zone, arguments.ArgAt(1)); - - const auto& function = Function::Handle(zone, closure.function()); - const ArgumentsDescriptor args_desc(descriptor); - if (!function.AreValidArguments(args_desc, nullptr)) { - arguments.SetReturn(Bool::False()); - } else if (!closure.IsGeneric(thread) && args_desc.TypeArgsLen() > 0) { - // The arguments may be valid for the closure function itself, but if the - // closure has delayed type arguments, no type arguments should be provided. - arguments.SetReturn(Bool::False()); - } else { - arguments.SetReturn(Bool::True()); - } -} - -// Resolve 'call' function of receiver. -// Arg0: receiver (not a closure). -// Arg1: arguments descriptor -// Return value: 'call' function'. -DEFINE_RUNTIME_ENTRY(ResolveCallFunction, 2) { - ASSERT(FLAG_enable_interpreter); - const Instance& receiver = Instance::CheckedHandle(zone, arguments.ArgAt(0)); - const Array& descriptor = Array::CheckedHandle(zone, arguments.ArgAt(1)); - ArgumentsDescriptor args_desc(descriptor); - ASSERT(!receiver.IsClosure()); // Interpreter tests for closure. - Class& cls = Class::Handle(zone, receiver.clazz()); - Function& call_function = Function::Handle( - zone, - Resolver::ResolveDynamicForReceiverClass(cls, Symbols::Call(), args_desc, - /*allow_add=*/false)); - arguments.SetReturn(call_function); -} - // Helper routine for tracing a type check. static void PrintTypeCheck(const char* message, const Instance& instance, @@ -888,7 +808,6 @@ DEFINE_RUNTIME_ENTRY(TypeCheck, 7) { DartFrameIterator iterator(thread, StackFrameIterator::kNoCrossThreadIteration); StackFrame* caller_frame = iterator.NextFrame(); - ASSERT(!caller_frame->is_interpreted()); const Code& caller_code = Code::Handle(zone, caller_frame->LookupDartCode()); const ObjectPool& pool = @@ -971,7 +890,6 @@ DEFINE_RUNTIME_ENTRY(TypeCheck, 7) { DartFrameIterator iterator(thread, StackFrameIterator::kNoCrossThreadIteration); StackFrame* caller_frame = iterator.NextFrame(); - ASSERT(!caller_frame->is_interpreted()); const Code& caller_code = Code::Handle(zone, caller_frame->LookupDartCode()); const ObjectPool& pool = @@ -1059,7 +977,6 @@ DEFINE_RUNTIME_ENTRY(PatchStaticCall, 0) { StackFrameIterator::kNoCrossThreadIteration); StackFrame* caller_frame = iterator.NextFrame(); ASSERT(caller_frame != NULL); - ASSERT(!caller_frame->is_interpreted()); const Code& caller_code = Code::Handle(zone, caller_frame->LookupDartCode()); ASSERT(!caller_code.IsNull()); ASSERT(caller_code.is_optimized()); @@ -1100,9 +1017,7 @@ DEFINE_RUNTIME_ENTRY(BreakpointRuntimeHandler, 0) { StackFrame* caller_frame = iterator.NextFrame(); ASSERT(caller_frame != NULL); Code& orig_stub = Code::Handle(zone); - if (!caller_frame->is_interpreted()) { - orig_stub = isolate->debugger()->GetPatchedStubAddress(caller_frame->pc()); - } + orig_stub = isolate->debugger()->GetPatchedStubAddress(caller_frame->pc()); const Error& error = Error::Handle(zone, isolate->debugger()->PauseBreakpoint()); ThrowIfError(error); @@ -1217,7 +1132,6 @@ static void TrySwitchInstanceCall(const ICData& ic_data, ASSERT(caller_frame->IsDartFrame()); // Monomorphic/megamorphic calls are only for unoptimized code. - if (caller_frame->is_interpreted()) return; Zone* zone = thread->zone(); const Code& caller_code = Code::Handle(zone, caller_frame->LookupDartCode()); if (caller_code.is_optimized()) return; @@ -1249,12 +1163,6 @@ static void TrySwitchInstanceCall(const ICData& ic_data, return; } - // Avoid forcing foreground compilation if target function is still - // interpreted. - if (FLAG_enable_interpreter && !target_function.HasCode()) { - return; - } - const Array& data = Array::Handle(zone, ic_data.entries()); const Code& target = Code::Handle(zone, target_function.EnsureHasCode()); CodePatcher::PatchInstanceCallAt(caller_frame->pc(), caller_code, data, @@ -2168,41 +2076,6 @@ DEFINE_RUNTIME_ENTRY(SwitchableCallMiss, 2) { /*use_force_growth=*/true); } -// Handles interpreted interface call cache miss. -// Arg0: receiver -// Arg1: target name -// Arg2: arguments descriptor -// Returns: target function (can only be null if !FLAG_lazy_dispatchers) -// Modifies the instance call table in current interpreter. -DEFINE_RUNTIME_ENTRY(InterpretedInstanceCallMissHandler, 3) { -#if defined(DART_PRECOMPILED_RUNTIME) - UNREACHABLE(); -#else - ASSERT(FLAG_enable_interpreter); - const Instance& receiver = Instance::CheckedHandle(zone, arguments.ArgAt(0)); - const String& target_name = String::CheckedHandle(zone, arguments.ArgAt(1)); - const Array& arg_desc = Array::CheckedHandle(zone, arguments.ArgAt(2)); - - ArgumentsDescriptor arguments_descriptor(arg_desc); - const Class& receiver_class = Class::Handle(zone, receiver.clazz()); - Function& target_function = Function::Handle(zone); - if (receiver_class.EnsureIsFinalized(thread) == Error::null()) { - target_function = - Resolver::ResolveDynamic(receiver, target_name, arguments_descriptor); - } - - // TODO(regis): In order to substitute 'simple_instance_of_function', the 2nd - // arg to the call, the type, is needed. - - if (target_function.IsNull()) { - target_function = - InlineCacheMissHelper(receiver_class, arg_desc, target_name); - } - ASSERT(!target_function.IsNull() || !FLAG_lazy_dispatchers); - arguments.SetReturn(target_function); -#endif -} - // Used to find the correct receiver and function to invoke or to fall back to // invoking noSuchMethod when lazy dispatchers are disabled. Returns the // result of the invocation or an Error. @@ -2390,37 +2263,6 @@ DEFINE_RUNTIME_ENTRY(NoSuchMethodFromPrologue, 4) { arguments.SetReturn(result); } -// Invoke appropriate noSuchMethod function (or in the case of no lazy -// dispatchers, walk the receiver to find the correct method to call). -// Arg0: receiver -// Arg1: function name. -// Arg2: arguments descriptor array. -// Arg3: arguments array. -DEFINE_RUNTIME_ENTRY(InvokeNoSuchMethod, 4) { - ASSERT(FLAG_enable_interpreter); - const Instance& receiver = Instance::CheckedHandle(zone, arguments.ArgAt(0)); - const String& original_function_name = - String::CheckedHandle(zone, arguments.ArgAt(1)); - const Array& orig_arguments_desc = - Array::CheckedHandle(zone, arguments.ArgAt(2)); - const Array& orig_arguments = Array::CheckedHandle(zone, arguments.ArgAt(3)); - - auto& result = Object::Handle(zone); - if (!FLAG_lazy_dispatchers) { - // Failing to find the method could be due to the lack of lazy invoke field - // dispatchers, so attempt a deeper search before calling noSuchMethod. - result = InvokeCallThroughGetterOrNoSuchMethod( - thread, zone, receiver, original_function_name, orig_arguments, - orig_arguments_desc); - } else { - result = - DartEntry::InvokeNoSuchMethod(thread, receiver, original_function_name, - orig_arguments, orig_arguments_desc); - } - ThrowIfError(result); - arguments.SetReturn(result); -} - #if !defined(PRODUCT) && !defined(DART_PRECOMPILED_RUNTIME) // The following code is used to stress test // - deoptimization @@ -2469,13 +2311,9 @@ static void HandleStackOverflowTestCases(Thread* thread) { ASSERT(frame != nullptr); Code& code = Code::Handle(); Function& function = Function::Handle(); - if (frame->is_interpreted()) { - function = frame->LookupDartFunction(); - } else { - code = frame->LookupDartCode(); - ASSERT(!code.IsNull()); - function = code.function(); - } + code = frame->LookupDartCode(); + ASSERT(!code.IsNull()); + function = code.function(); ASSERT(!function.IsNull()); const char* function_name = nullptr; if ((FLAG_deoptimize_filter != nullptr) || @@ -2557,13 +2395,9 @@ static void HandleStackOverflowTestCases(Thread* thread) { int num_vars = 0; // Variable locations and number are unknown when precompiling. #if !defined(DART_PRECOMPILED_RUNTIME) - // NumLocalVariables() can call EnsureHasUnoptimizedCode() for - // non-interpreted functions. if (!frame->function().ForceOptimize()) { - if (!frame->IsInterpreted()) { - // Ensure that we have unoptimized code. - frame->function().EnsureHasCompiledUnoptimizedCode(); - } + // Ensure that we have unoptimized code. + frame->function().EnsureHasCompiledUnoptimizedCode(); num_vars = frame->NumLocalVariables(); } #endif @@ -2652,8 +2486,7 @@ DEFINE_RUNTIME_ENTRY(AllocateMint, 0) { DEFINE_RUNTIME_ENTRY(StackOverflow, 0) { #if defined(USING_SIMULATOR) uword stack_pos = Simulator::Current()->get_sp(); - // If simulator was never called (for example, in pure - // interpreted mode) it may return 0 as a value of SPREG. + // If simulator was never called it may return 0 as a value of SPREG. if (stack_pos == 0) { // Use any reasonable value which would not be treated // as stack overflow. @@ -2667,36 +2500,15 @@ DEFINE_RUNTIME_ENTRY(StackOverflow, 0) { // persist. uword stack_overflow_flags = thread->GetAndClearStackOverflowFlags(); - bool interpreter_stack_overflow = false; -#if !defined(DART_PRECOMPILED_RUNTIME) - if (FLAG_enable_interpreter) { - // Do not allocate an interpreter, if none is allocated yet. - Interpreter* interpreter = thread->interpreter(); - if (interpreter != NULL) { - interpreter_stack_overflow = - interpreter->get_sp() >= interpreter->overflow_stack_limit(); - } - } -#endif // !defined(DART_PRECOMPILED_RUNTIME) - // If an interrupt happens at the same time as a stack overflow, we // process the stack overflow now and leave the interrupt for next // time. - if (interpreter_stack_overflow || !thread->os_thread()->HasStackHeadroom() || + if (!thread->os_thread()->HasStackHeadroom() || IsCalleeFrameOf(thread->saved_stack_limit(), stack_pos)) { if (FLAG_verbose_stack_overflow) { - OS::PrintErr("Stack overflow in %s\n", - interpreter_stack_overflow ? "interpreter" : "native code"); + OS::PrintErr("Stack overflow\n"); OS::PrintErr(" Native SP = %" Px ", stack limit = %" Px "\n", stack_pos, thread->saved_stack_limit()); -#if !defined(DART_PRECOMPILED_RUNTIME) - if (thread->interpreter() != nullptr) { - OS::PrintErr(" Interpreter SP = %" Px ", stack limit = %" Px "\n", - thread->interpreter()->get_sp(), - thread->interpreter()->overflow_stack_limit()); - } -#endif // !defined(DART_PRECOMPILED_RUNTIME) - OS::PrintErr("Call stack:\n"); OS::PrintErr("size | frame\n"); StackFrameIterator frames(ValidationPolicy::kDontValidateFrames, thread, @@ -2704,14 +2516,9 @@ DEFINE_RUNTIME_ENTRY(StackOverflow, 0) { uword fp = stack_pos; StackFrame* frame = frames.NextFrame(); while (frame != NULL) { - if (frame->is_interpreted() == interpreter_stack_overflow) { - uword delta = interpreter_stack_overflow ? (fp - frame->fp()) - : (frame->fp() - fp); - fp = frame->fp(); - OS::PrintErr("%4" Pd " %s\n", delta, frame->ToCString()); - } else { - OS::PrintErr(" %s\n", frame->ToCString()); - } + uword delta = (frame->fp() - fp); + fp = frame->fp(); + OS::PrintErr("%4" Pd " %s\n", delta, frame->ToCString()); frame = frames.NextFrame(); } } @@ -2756,46 +2563,6 @@ DEFINE_RUNTIME_ENTRY(TraceICCall, 2) { ic_data.NumberOfChecks(), function.ToFullyQualifiedCString()); } -// This is called from interpreter when function usage counter reached -// compilation threshold and function needs to be compiled. -DEFINE_RUNTIME_ENTRY(CompileInterpretedFunction, 1) { -#if !defined(DART_PRECOMPILED_RUNTIME) - const Function& function = Function::CheckedHandle(zone, arguments.ArgAt(0)); - ASSERT(!function.IsNull()); - ASSERT(FLAG_enable_interpreter); - -#if !defined(PRODUCT) - if (Debugger::IsDebugging(thread, function)) { - return; - } -#endif // !defined(PRODUCT) - - if (FLAG_background_compilation) { - if (!BackgroundCompiler::IsDisabled(isolate, - /* optimizing_compilation = */ false) && - function.is_background_optimizable()) { - // Ensure background compiler is running, if not start it. - BackgroundCompiler::Start(isolate); - // Reduce the chance of triggering a compilation while the function is - // being compiled in the background. INT32_MIN should ensure that it - // takes long time to trigger a compilation. - // Note that the background compilation queue rejects duplicate entries. - function.SetUsageCounter(INT32_MIN); - isolate->background_compiler()->Compile(function); - return; - } - } - - // Reset usage counter for future optimization. - function.SetUsageCounter(0); - Object& result = - Object::Handle(zone, Compiler::CompileFunction(thread, function)); - ThrowIfError(result); -#else - UNREACHABLE(); -#endif // !DART_PRECOMPILED_RUNTIME -} - // This is called from function that needs to be optimized. // The requesting function can be already optimized (reoptimization). // Returns the Code object where to continue execution. @@ -3035,7 +2802,6 @@ void DeoptimizeAt(const Code& optimized_code, StackFrame* frame) { // N.B.: Update the pending deopt table before updating the frame. The // profiler may attempt a stack walk in between. - ASSERT(!frame->is_interpreted()); thread->isolate()->AddPendingDeopt(frame->fp(), deopt_pc); frame->MarkForLazyDeopt(); @@ -3057,12 +2823,9 @@ void DeoptimizeFunctionsOnStack() { StackFrame* frame = iterator.NextFrame(); Code& optimized_code = Code::Handle(); while (frame != NULL) { - if (!frame->is_interpreted()) { - optimized_code = frame->LookupDartCode(); - if (optimized_code.is_optimized() && - !optimized_code.is_force_optimized()) { - DeoptimizeAt(optimized_code, frame); - } + optimized_code = frame->LookupDartCode(); + if (optimized_code.is_optimized() && !optimized_code.is_force_optimized()) { + DeoptimizeAt(optimized_code, frame); } frame = iterator.NextFrame(); } @@ -3410,65 +3173,6 @@ DEFINE_RAW_LEAF_RUNTIME_ENTRY( true /* is_float */, reinterpret_cast(static_cast(&atan))); -// Interpret a function call. Should be called only for non-jitted functions. -// argc indicates the number of arguments, including the type arguments. -// argv points to the first argument. -// If argc < 0, arguments are passed at decreasing memory addresses from argv. -extern "C" uword /*ObjectPtr*/ InterpretCall(uword /*FunctionPtr*/ function_in, - uword /*ArrayPtr*/ argdesc_in, - intptr_t argc, - ObjectPtr* argv, - Thread* thread) { -#if defined(DART_PRECOMPILED_RUNTIME) - UNREACHABLE(); -#else - FunctionPtr function = static_cast(function_in); - ArrayPtr argdesc = static_cast(argdesc_in); - ASSERT(FLAG_enable_interpreter); - Interpreter* interpreter = Interpreter::Current(); -#if defined(DEBUG) - uword exit_fp = thread->top_exit_frame_info(); - ASSERT(exit_fp != 0); - ASSERT(thread == Thread::Current()); - // Caller is InterpretCall stub called from generated code. - // We stay in "in generated code" execution state when interpreting code. - ASSERT(thread->execution_state() == Thread::kThreadInGenerated); - ASSERT(!Function::HasCode(function)); - ASSERT(Function::HasBytecode(function)); - ASSERT(interpreter != NULL); -#endif - // Tell MemorySanitizer 'argv' is initialized by generated code. - if (argc < 0) { - MSAN_UNPOISON(argv - argc, -argc * sizeof(ObjectPtr)); - } else { - MSAN_UNPOISON(argv, argc * sizeof(ObjectPtr)); - } - ObjectPtr result = interpreter->Call(function, argdesc, argc, argv, thread); - DEBUG_ASSERT(thread->top_exit_frame_info() == exit_fp); - if (IsErrorClassId(result->GetClassIdMayBeSmi())) { - // Must not leak handles in the caller's zone. - HANDLESCOPE(thread); - // Protect the result in a handle before transitioning, which may trigger - // GC. - const Error& error = Error::Handle(Error::RawCast(result)); - // Propagating an error may cause allocation. Check if we need to block for - // a safepoint by switching to "in VM" execution state. - TransitionGeneratedToVM transition(thread); - Exceptions::PropagateError(error); - } - return static_cast(result); -#endif // defined(DART_PRECOMPILED_RUNTIME) -} - -uword RuntimeEntry::InterpretCallEntry() { - uword entry = reinterpret_cast(InterpretCall); -#if defined(USING_SIMULATOR) - entry = Simulator::RedirectExternalReference(entry, - Simulator::kLeafRuntimeCall, 5); -#endif - return entry; -} - extern "C" void DFLRT_EnterSafepoint(NativeArguments __unusable_) { CHECK_STACK_ALIGNMENT; TRACE_RUNTIME_CALL("%s", "EnterSafepoint"); diff --git a/runtime/vm/runtime_entry.h b/runtime/vm/runtime_entry.h index bede33e6ce6..d4ce29345cf 100644 --- a/runtime/vm/runtime_entry.h +++ b/runtime/vm/runtime_entry.h @@ -57,8 +57,6 @@ class RuntimeEntry : public BaseRuntimeEntry { NOT_IN_PRECOMPILED(void Call(compiler::Assembler* assembler, intptr_t argument_count) const); - static uword InterpretCallEntry(); - protected: NOT_IN_PRECOMPILED(static void CallInternal(const RuntimeEntry* runtime_entry, compiler::Assembler* assembler, diff --git a/runtime/vm/runtime_entry_arm.cc b/runtime/vm/runtime_entry_arm.cc index 9502b49b1f4..752ca63bc5e 100644 --- a/runtime/vm/runtime_entry_arm.cc +++ b/runtime/vm/runtime_entry_arm.cc @@ -56,7 +56,7 @@ void RuntimeEntry::CallInternal(const RuntimeEntry* runtime_entry, __ str(TMP, compiler::Address(THR, compiler::target::Thread::vm_tag_offset())); __ blx(TMP); - __ LoadImmediate(TMP, VMTag::kDartCompiledTagId); + __ LoadImmediate(TMP, VMTag::kDartTagId); __ str(TMP, compiler::Address(THR, compiler::target::Thread::vm_tag_offset())); ASSERT((kAbiPreservedCpuRegs & (1 << THR)) != 0); diff --git a/runtime/vm/runtime_entry_arm64.cc b/runtime/vm/runtime_entry_arm64.cc index 5fd14b5ddbf..1580e1aa41e 100644 --- a/runtime/vm/runtime_entry_arm64.cc +++ b/runtime/vm/runtime_entry_arm64.cc @@ -69,7 +69,7 @@ void RuntimeEntry::CallInternal(const RuntimeEntry* runtime_entry, compiler::Address(THR, Thread::OffsetFromThread(runtime_entry))); __ str(TMP, compiler::Address(THR, Thread::vm_tag_offset())); __ blr(TMP); - __ LoadImmediate(TMP, VMTag::kDartCompiledTagId); + __ LoadImmediate(TMP, VMTag::kDartTagId); __ str(TMP, compiler::Address(THR, Thread::vm_tag_offset())); __ mov(SP, kCallLeafRuntimeCalleeSaveScratch2); __ mov(CSP, kCallLeafRuntimeCalleeSaveScratch1); diff --git a/runtime/vm/runtime_entry_ia32.cc b/runtime/vm/runtime_entry_ia32.cc index 22f67d7f779..8bba816453b 100644 --- a/runtime/vm/runtime_entry_ia32.cc +++ b/runtime/vm/runtime_entry_ia32.cc @@ -36,7 +36,7 @@ void RuntimeEntry::CallInternal(const RuntimeEntry* runtime_entry, __ movl(compiler::Assembler::VMTagAddress(), EAX); __ call(EAX); __ movl(compiler::Assembler::VMTagAddress(), - compiler::Immediate(VMTag::kDartCompiledTagId)); + compiler::Immediate(VMTag::kDartTagId)); } else { // Argument count is not checked here, but in the runtime entry for a more // informative error message. diff --git a/runtime/vm/runtime_entry_list.h b/runtime/vm/runtime_entry_list.h index 394c01dd3fd..40f5bd88cd4 100644 --- a/runtime/vm/runtime_entry_list.h +++ b/runtime/vm/runtime_entry_list.h @@ -12,13 +12,9 @@ namespace dart { V(AllocateTypedData) \ V(AllocateContext) \ V(AllocateObject) \ - V(AllocateSubtypeTestCache) \ V(BreakpointRuntimeHandler) \ V(SingleStepHandler) \ V(CloneContext) \ - V(GetFieldForDispatch) \ - V(ClosureArgumentsValid) \ - V(ResolveCallFunction) \ V(FixCallersTarget) \ V(FixCallersTargetMonomorphic) \ V(FixAllocationStubTarget) \ @@ -26,7 +22,6 @@ namespace dart { V(InlineCacheMissHandlerTwoArgs) \ V(StaticCallMissHandlerOneArg) \ V(StaticCallMissHandlerTwoArgs) \ - V(InterpretedInstanceCallMissHandler) \ V(Instanceof) \ V(SubtypeCheck) \ V(TypeCheck) \ @@ -35,7 +30,6 @@ namespace dart { V(InstantiateTypeArguments) \ V(NoSuchMethodFromCallStub) \ V(NoSuchMethodFromPrologue) \ - V(InvokeNoSuchMethod) \ V(OptimizeInvokedFunction) \ V(TraceICCall) \ V(PatchStaticCall) \ @@ -58,7 +52,6 @@ namespace dart { V(InitStaticField) \ V(LateInitializationError) \ V(CompileFunction) \ - V(CompileInterpretedFunction) \ V(SwitchableCallMiss) \ V(NotLoaded) diff --git a/runtime/vm/runtime_entry_x64.cc b/runtime/vm/runtime_entry_x64.cc index caaa2a4db1a..78d3eada2d3 100644 --- a/runtime/vm/runtime_entry_x64.cc +++ b/runtime/vm/runtime_entry_x64.cc @@ -37,7 +37,7 @@ void RuntimeEntry::CallInternal(const RuntimeEntry* runtime_entry, __ movq(compiler::Assembler::VMTagAddress(), RAX); __ CallCFunction(RAX); __ movq(compiler::Assembler::VMTagAddress(), - compiler::Immediate(VMTag::kDartCompiledTagId)); + compiler::Immediate(VMTag::kDartTagId)); ASSERT((CallingConventions::kCalleeSaveCpuRegisters & (1 << THR)) != 0); ASSERT((CallingConventions::kCalleeSaveCpuRegisters & (1 << PP)) != 0); } else { diff --git a/runtime/vm/service.cc b/runtime/vm/service.cc index 3a89d30a7c8..23dfdde7021 100644 --- a/runtime/vm/service.cc +++ b/runtime/vm/service.cc @@ -1986,10 +1986,6 @@ static ObjectPtr LookupHeapObjectCode(Isolate* isolate, if (!code.IsNull()) { return code.raw(); } - Bytecode& bytecode = Bytecode::Handle(Bytecode::FindCode(pc)); - if (!bytecode.IsNull()) { - return bytecode.raw(); - } // Not found. return Object::sentinel().raw(); diff --git a/runtime/vm/simulator_arm.cc b/runtime/vm/simulator_arm.cc index 40fbe7ce2db..316a56b3ccb 100644 --- a/runtime/vm/simulator_arm.cc +++ b/runtime/vm/simulator_arm.cc @@ -320,7 +320,6 @@ void SimulatorDebugger::PrintBacktrace() { Code& unoptimized_code = Code::Handle(Z); while (frame != NULL) { if (frame->IsDartFrame()) { - ASSERT(!frame->is_interpreted()); // Not yet supported. code = frame->LookupDartCode(); function = code.function(); if (code.is_optimized()) { @@ -3660,7 +3659,7 @@ void Simulator::JumpToFrame(uword pc, uword sp, uword fp, Thread* thread) { set_register(FP, static_cast(fp)); set_register(THR, reinterpret_cast(thread)); // Set the tag. - thread->set_vm_tag(VMTag::kDartCompiledTagId); + thread->set_vm_tag(VMTag::kDartTagId); // Clear top exit frame. thread->set_top_exit_frame_info(0); // Restore pool pointer. diff --git a/runtime/vm/simulator_arm64.cc b/runtime/vm/simulator_arm64.cc index 786919613c2..b80c9330e2e 100644 --- a/runtime/vm/simulator_arm64.cc +++ b/runtime/vm/simulator_arm64.cc @@ -348,7 +348,6 @@ void SimulatorDebugger::PrintBacktrace() { Code& unoptimized_code = Code::Handle(Z); while (frame != NULL) { if (frame->IsDartFrame()) { - ASSERT(!frame->is_interpreted()); // Not yet supported. code = frame->LookupDartCode(); function = code.function(); if (code.is_optimized()) { @@ -3715,7 +3714,7 @@ void Simulator::JumpToFrame(uword pc, uword sp, uword fp, Thread* thread) { set_register(NULL, FP, static_cast(fp)); set_register(NULL, THR, reinterpret_cast(thread)); // Set the tag. - thread->set_vm_tag(VMTag::kDartCompiledTagId); + thread->set_vm_tag(VMTag::kDartTagId); // Clear top exit frame. thread->set_top_exit_frame_info(0); // Restore pool pointer. diff --git a/runtime/vm/snapshot.cc b/runtime/vm/snapshot.cc index 5c0d911c15f..10a5996f375 100644 --- a/runtime/vm/snapshot.cc +++ b/runtime/vm/snapshot.cc @@ -1138,7 +1138,7 @@ bool SnapshotWriter::CheckAndWritePredefinedObject(ObjectPtr rawobj) { // Check if it is a code object in that case just write a Null object // as we do not want code objects in the snapshot. - if ((cid == kCodeCid) || (cid == kBytecodeCid)) { + if (cid == kCodeCid) { WriteVMIsolateObject(kNullObject); return true; } diff --git a/runtime/vm/snapshot.h b/runtime/vm/snapshot.h index 94aa3e7e272..90e62a09102 100644 --- a/runtime/vm/snapshot.h +++ b/runtime/vm/snapshot.h @@ -138,9 +138,6 @@ class Snapshot { static bool IncludesCode(Kind kind) { return (kind == kFullJIT) || (kind == kFullAOT); } - static bool IncludesBytecode(Kind kind) { - return (kind == kFull) || (kind == kFullCore) || (kind == kFullJIT); - } const uint8_t* Addr() const { return reinterpret_cast(this); } diff --git a/runtime/vm/snapshot_test.cc b/runtime/vm/snapshot_test.cc index ed0383c4981..f793f2e8220 100644 --- a/runtime/vm/snapshot_test.cc +++ b/runtime/vm/snapshot_test.cc @@ -381,7 +381,6 @@ ISOLATE_UNIT_TEST_CASE(SerializeSingletons) { TEST_ROUND_TRIP_IDENTICAL(Object::script_class()); TEST_ROUND_TRIP_IDENTICAL(Object::library_class()); TEST_ROUND_TRIP_IDENTICAL(Object::code_class()); - TEST_ROUND_TRIP_IDENTICAL(Object::bytecode_class()); TEST_ROUND_TRIP_IDENTICAL(Object::instructions_class()); TEST_ROUND_TRIP_IDENTICAL(Object::pc_descriptors_class()); TEST_ROUND_TRIP_IDENTICAL(Object::exception_handlers_class()); diff --git a/runtime/vm/source_report.cc b/runtime/vm/source_report.cc index ba45ab67c53..4ed6a46d8a5 100644 --- a/runtime/vm/source_report.cc +++ b/runtime/vm/source_report.cc @@ -108,11 +108,7 @@ bool SourceReport::ShouldSkipFunction(const Function& func) { func.IsRedirectingFactory() || func.is_synthetic()) { return true; } - // Note that context_scope() remains null for closures declared in bytecode, - // because the same information is retrieved from the parent's local variable - // descriptors. - // See IsLocalFunction() case in BytecodeReader::ComputeLocalVarDescriptors. - if (!func.is_declared_in_bytecode() && func.IsNonImplicitClosureFunction() && + if (func.IsNonImplicitClosureFunction() && (func.context_scope() == ContextScope::null())) { // TODO(iposva): This can arise if we attempt to compile an inner function // before we have compiled its enclosing function or if the enclosing @@ -198,10 +194,7 @@ bool SourceReport::ScriptIsLoadedByLibrary(const Script& script, void SourceReport::PrintCallSitesData(JSONObject* jsobj, const Function& function, const Code& code) { - if (code.IsNull()) { - // TODO(regis): implement for bytecode. - return; - } + ASSERT(!code.IsNull()); const TokenPosition begin_pos = function.token_pos(); const TokenPosition end_pos = function.end_token_pos(); @@ -234,10 +227,7 @@ void SourceReport::PrintCallSitesData(JSONObject* jsobj, void SourceReport::PrintCoverageData(JSONObject* jsobj, const Function& function, const Code& code) { - if (code.IsNull()) { - // TODO(regis): implement for bytecode. - return; - } + ASSERT(!code.IsNull()); const TokenPosition begin_pos = function.token_pos(); const TokenPosition end_pos = function.end_token_pos(); @@ -319,63 +309,24 @@ void SourceReport::PrintPossibleBreakpointsData(JSONObject* jsobj, BitVector possible(zone(), func_length); - if (code.IsNull()) { - const Bytecode& bytecode = Bytecode::Handle(func.bytecode()); - ASSERT(!bytecode.IsNull()); - kernel::BytecodeSourcePositionsIterator iter(zone(), bytecode); - intptr_t token_offset = -1; - uword pc_offset = kUwordMax; - // Ignore all possible breakpoint positions until the first DebugCheck - // opcode of the function. - const uword debug_check_pc = bytecode.GetFirstDebugCheckOpcodePc(); - if (debug_check_pc != 0) { - const uword debug_check_pc_offset = - debug_check_pc - bytecode.PayloadStart(); - while (iter.MoveNext()) { - if (pc_offset != kUwordMax) { - // Check that there is at least one 'debug checked' opcode in the last - // source position range. - if (bytecode.GetDebugCheckedOpcodeReturnAddress( - pc_offset, iter.PcOffset()) != 0) { - possible.Add(token_offset); - } - pc_offset = kUwordMax; - } - const TokenPosition token_pos = iter.TokenPos(); - if ((token_pos < begin_pos) || (token_pos > end_pos)) { - // Does not correspond to a valid source position. - continue; - } - if (iter.PcOffset() < debug_check_pc_offset) { - // No breakpoints in prologue. - continue; - } - pc_offset = iter.PcOffset(); - token_offset = token_pos.Pos() - begin_pos.Pos(); - } - } - if (pc_offset != kUwordMax && bytecode.GetDebugCheckedOpcodeReturnAddress( - pc_offset, bytecode.Size()) != 0) { - possible.Add(token_offset); - } - } else { - const uint8_t kSafepointKind = - (PcDescriptorsLayout::kIcCall | PcDescriptorsLayout::kUnoptStaticCall | - PcDescriptorsLayout::kRuntimeCall); + ASSERT(!code.IsNull()); - const PcDescriptors& descriptors = - PcDescriptors::Handle(zone(), code.pc_descriptors()); + const uint8_t kSafepointKind = + (PcDescriptorsLayout::kIcCall | PcDescriptorsLayout::kUnoptStaticCall | + PcDescriptorsLayout::kRuntimeCall); - PcDescriptors::Iterator iter(descriptors, kSafepointKind); - while (iter.MoveNext()) { - const TokenPosition token_pos = iter.TokenPos(); - if ((token_pos < begin_pos) || (token_pos > end_pos)) { - // Does not correspond to a valid source position. - continue; - } - intptr_t token_offset = token_pos.Pos() - begin_pos.Pos(); - possible.Add(token_offset); + const PcDescriptors& descriptors = + PcDescriptors::Handle(zone(), code.pc_descriptors()); + + PcDescriptors::Iterator iter(descriptors, kSafepointKind); + while (iter.MoveNext()) { + const TokenPosition token_pos = iter.TokenPos(); + if ((token_pos < begin_pos) || (token_pos > end_pos)) { + // Does not correspond to a valid source position. + continue; } + intptr_t token_offset = token_pos.Pos() - begin_pos.Pos(); + possible.Add(token_offset); } JSONArray bpts(jsobj, "possibleBreakpoints"); @@ -454,16 +405,7 @@ void SourceReport::VisitFunction(JSONArray* jsarr, const Function& func) { const TokenPosition end_pos = func.end_token_pos(); Code& code = Code::Handle(zone(), func.unoptimized_code()); - Bytecode& bytecode = Bytecode::Handle(zone()); - if (FLAG_enable_interpreter && !func.HasCode() && func.HasBytecode()) { - // When the bytecode of a function is loaded, the function code is not null, - // but pointing to the stub to interpret the bytecode. The various Print - // functions below take code as an argument and know to process the bytecode - // if code is null. - code = Code::null(); // Ignore installed stub to interpret bytecode. - bytecode = func.bytecode(); - } - if (code.IsNull() && bytecode.IsNull()) { + if (code.IsNull()) { if (func.HasCode() || (compile_mode_ == kForceCompile)) { const Error& err = Error::Handle(Compiler::EnsureUnoptimizedCode(thread(), func)); @@ -478,10 +420,6 @@ void SourceReport::VisitFunction(JSONArray* jsarr, const Function& func) { return; } code = func.unoptimized_code(); - if (FLAG_enable_interpreter && !func.HasCode() && func.HasBytecode()) { - code = Code::null(); // Ignore installed stub to interpret bytecode. - bytecode = func.bytecode(); - } } else { // This function has not been compiled yet. JSONObject range(jsarr); @@ -492,7 +430,7 @@ void SourceReport::VisitFunction(JSONArray* jsarr, const Function& func) { return; } } - ASSERT(!code.IsNull() || !bytecode.IsNull()); + ASSERT(!code.IsNull()); // We skip compiled async functions. Once an async function has // been compiled, there is another function with the same range which @@ -503,7 +441,7 @@ void SourceReport::VisitFunction(JSONArray* jsarr, const Function& func) { range.AddProperty("scriptIndex", GetScriptIndex(script)); range.AddProperty("startPos", begin_pos); range.AddProperty("endPos", end_pos); - range.AddProperty("compiled", true); // bytecode or code. + range.AddProperty("compiled", true); if (IsReportRequested(kCallSites)) { PrintCallSitesData(&range, func, code); @@ -590,8 +528,6 @@ void SourceReport::VisitLibrary(JSONArray* jsarr, const Library& lib) { } void SourceReport::VisitClosures(JSONArray* jsarr) { - // Note that closures declared in bytecode are not visited here, but in - // VisitFunction while traversing the object pool of their owner functions. const GrowableObjectArray& closures = GrowableObjectArray::Handle( thread()->isolate()->object_store()->closure_functions()); diff --git a/runtime/vm/stack_frame.cc b/runtime/vm/stack_frame.cc index 9df6e3c52c4..6d6f0134269 100644 --- a/runtime/vm/stack_frame.cc +++ b/runtime/vm/stack_frame.cc @@ -26,8 +26,6 @@ namespace dart { -DECLARE_FLAG(bool, enable_interpreter); - const FrameLayout invalid_frame_layout = { /*.first_object_from_fp = */ -1, /*.last_fixed_object_from_fp = */ -1, @@ -151,10 +149,6 @@ bool StackFrame::IsBareInstructionsStubFrame() const { } bool StackFrame::IsStubFrame() const { - if (is_interpreted()) { - return false; - } - if (FLAG_precompiled_mode && FLAG_use_bare_instructions) { return IsBareInstructionsStubFrame(); } @@ -177,15 +171,6 @@ const char* StackFrame::ToCString() const { ASSERT(thread_ == Thread::Current()); Zone* zone = Thread::Current()->zone(); if (IsDartFrame()) { - if (is_interpreted()) { - const Bytecode& bytecode = Bytecode::Handle(zone, LookupDartBytecode()); - ASSERT(!bytecode.IsNull()); - return zone->PrintToString("[%-8s : sp(%#" Px ") fp(%#" Px ") pc(%#" Px - " offset:0x%" Px ") %s ]", - GetName(), sp(), fp(), pc(), - pc() - bytecode.PayloadStart(), - bytecode.FullyQualifiedName()); - } const Code& code = Code::Handle(zone, LookupDartCode()); ASSERT(!code.IsNull()); const auto& owner = Object::Handle( @@ -207,16 +192,11 @@ const char* StackFrame::ToCString() const { void ExitFrame::VisitObjectPointers(ObjectPointerVisitor* visitor) { ASSERT(visitor != NULL); - // Visit pc marker and saved pool pointer, or, for interpreted frame, code - // object and function object. - ObjectPtr* last_fixed = - reinterpret_cast(fp()) + - (is_interpreted() ? kKBCLastFixedObjectSlotFromFp - : runtime_frame_layout.first_object_from_fp); - ObjectPtr* first_fixed = - reinterpret_cast(fp()) + - (is_interpreted() ? kKBCFirstObjectSlotFromFp - : runtime_frame_layout.last_fixed_object_from_fp); + // Visit pc marker and saved pool pointer. + ObjectPtr* last_fixed = reinterpret_cast(fp()) + + runtime_frame_layout.first_object_from_fp; + ObjectPtr* first_fixed = reinterpret_cast(fp()) + + runtime_frame_layout.last_fixed_object_from_fp; if (first_fixed <= last_fixed) { visitor->VisitPointers(first_fixed, last_fixed); } else { @@ -228,12 +208,9 @@ void ExitFrame::VisitObjectPointers(ObjectPointerVisitor* visitor) { void EntryFrame::VisitObjectPointers(ObjectPointerVisitor* visitor) { ASSERT(visitor != NULL); // Visit objects between SP and (FP - callee_save_area). - ObjectPtr* first = is_interpreted() ? reinterpret_cast(fp()) + - kKBCSavedArgDescSlotFromEntryFp - : reinterpret_cast(sp()); - ObjectPtr* last = is_interpreted() ? reinterpret_cast(sp()) - : reinterpret_cast(fp()) + - kExitLinkSlotFromEntryFp - 1; + ObjectPtr* first = reinterpret_cast(sp()); + ObjectPtr* last = + reinterpret_cast(fp()) + kExitLinkSlotFromEntryFp - 1; // There may not be any pointer to visit; in this case, first > last. visitor->VisitPointers(first, last); } @@ -253,18 +230,14 @@ void StackFrame::VisitObjectPointers(ObjectPointerVisitor* visitor) { code = GetCodeObject(); } else { ObjectPtr pc_marker = *(reinterpret_cast( - fp() + ((is_interpreted() ? kKBCPcMarkerSlotFromFp - : runtime_frame_layout.code_from_fp) * - kWordSize))); + fp() + (runtime_frame_layout.code_from_fp * kWordSize))); // May forward raw code. Note we don't just visit the pc marker slot first // because the visitor's forwarding might not be idempotent. visitor->VisitPointer(&pc_marker); if (pc_marker->IsHeapObject() && (pc_marker->GetClassId() == kCodeCid)) { code ^= pc_marker; } else { - ASSERT(pc_marker == Object::null() || - (is_interpreted() && (!pc_marker->IsHeapObject() || - (pc_marker->GetClassId() == kBytecodeCid)))); + ASSERT(pc_marker == Object::null()); } } @@ -288,9 +261,6 @@ void StackFrame::VisitObjectPointers(ObjectPointerVisitor* visitor) { const uword start = code.PayloadStart(); const uint32_t pc_offset = pc() - start; if (it.Find(pc_offset)) { - if (is_interpreted()) { - UNIMPLEMENTED(); - } ObjectPtr* first = reinterpret_cast(sp()); ObjectPtr* last = reinterpret_cast( fp() + (runtime_frame_layout.first_local_from_fp * kWordSize)); @@ -348,33 +318,14 @@ void StackFrame::VisitObjectPointers(ObjectPointerVisitor* visitor) { // For normal unoptimized Dart frames and Stub frames each slot // between the first and last included are tagged objects. - if (is_interpreted()) { - // Do not visit caller's pc or caller's fp. - ObjectPtr* first = - reinterpret_cast(fp()) + kKBCFirstObjectSlotFromFp; - ObjectPtr* last = - reinterpret_cast(fp()) + kKBCLastFixedObjectSlotFromFp; - - visitor->VisitPointers(first, last); - } - ObjectPtr* first = - reinterpret_cast(is_interpreted() ? fp() : sp()); + ObjectPtr* first = reinterpret_cast(sp()); ObjectPtr* last = reinterpret_cast( - is_interpreted() - ? sp() - : fp() + (runtime_frame_layout.first_object_from_fp * kWordSize)); + fp() + (runtime_frame_layout.first_object_from_fp * kWordSize)); visitor->VisitPointers(first, last); } FunctionPtr StackFrame::LookupDartFunction() const { - if (is_interpreted()) { - ObjectPtr result = *(reinterpret_cast( - fp() + kKBCFunctionSlotFromFp * kWordSize)); - ASSERT((result == Object::null()) || - (result->GetClassId() == kFunctionCid)); - return static_cast(result); - } const Code& code = Code::Handle(LookupDartCode()); if (!code.IsNull()) { return code.function(); @@ -399,8 +350,6 @@ CodePtr StackFrame::LookupDartCode() const { } CodePtr StackFrame::GetCodeObject() const { - ASSERT(!is_interpreted()); - #if defined(DART_PRECOMPILED_RUNTIME) if (FLAG_precompiled_mode && FLAG_use_bare_instructions) { CodePtr code = ReversePc::Lookup(isolate_group(), pc(), @@ -424,27 +373,6 @@ CodePtr StackFrame::GetCodeObject() const { return static_cast(pc_marker); } -BytecodePtr StackFrame::LookupDartBytecode() const { -// We add a no gc scope to ensure that the code below does not trigger -// a GC as we are handling raw object references here. It is possible -// that the code is called while a GC is in progress, that is ok. -#if !defined(HOST_OS_WINDOWS) && !defined(HOST_OS_FUCHSIA) - // On Windows and Fuchsia, the profiler calls this from a separate thread - // where Thread::Current() is NULL, so we cannot create a NoSafepointScope. - NoSafepointScope no_safepoint; -#endif - return GetBytecodeObject(); -} - -BytecodePtr StackFrame::GetBytecodeObject() const { - ASSERT(is_interpreted()); - ObjectPtr pc_marker = *( - reinterpret_cast(fp() + kKBCPcMarkerSlotFromFp * kWordSize)); - ASSERT((pc_marker == Object::null()) || - (pc_marker->GetClassId() == kBytecodeCid)); - return static_cast(pc_marker); -} - bool StackFrame::FindExceptionHandler(Thread* thread, uword* handler_pc, bool* needs_stacktrace, @@ -452,28 +380,19 @@ bool StackFrame::FindExceptionHandler(Thread* thread, bool* is_optimized) const { REUSABLE_CODE_HANDLESCOPE(thread); Code& code = reused_code_handle.Handle(); - REUSABLE_BYTECODE_HANDLESCOPE(thread); - Bytecode& bytecode = reused_bytecode_handle.Handle(); REUSABLE_EXCEPTION_HANDLERS_HANDLESCOPE(thread); ExceptionHandlers& handlers = reused_exception_handlers_handle.Handle(); REUSABLE_PC_DESCRIPTORS_HANDLESCOPE(thread); PcDescriptors& descriptors = reused_pc_descriptors_handle.Handle(); uword start; - if (is_interpreted()) { - bytecode = LookupDartBytecode(); - ASSERT(!bytecode.IsNull()); - start = bytecode.PayloadStart(); - handlers = bytecode.exception_handlers(); - } else { - code = LookupDartCode(); - if (code.IsNull()) { - return false; // Stub frames do not have exception handlers. - } - start = code.PayloadStart(); - handlers = code.exception_handlers(); - descriptors = code.pc_descriptors(); - *is_optimized = code.is_optimized(); + code = LookupDartCode(); + if (code.IsNull()) { + return false; // Stub frames do not have exception handlers. } + start = code.PayloadStart(); + handlers = code.exception_handlers(); + descriptors = code.pc_descriptors(); + *is_optimized = code.is_optimized(); HandlerInfoCache* cache = thread->isolate()->handler_info_cache(); ExceptionHandlerInfo* info = cache->Lookup(pc()); if (info != NULL) { @@ -488,17 +407,13 @@ bool StackFrame::FindExceptionHandler(Thread* thread, } intptr_t try_index = -1; - if (is_interpreted()) { - try_index = bytecode.GetTryIndexAtPc(pc()); - } else { - uword pc_offset = pc() - code.PayloadStart(); - PcDescriptors::Iterator iter(descriptors, PcDescriptorsLayout::kAnyKind); - while (iter.MoveNext()) { - const intptr_t current_try_index = iter.TryIndex(); - if ((iter.PcOffset() == pc_offset) && (current_try_index != -1)) { - try_index = current_try_index; - break; - } + uword pc_offset = pc() - code.PayloadStart(); + PcDescriptors::Iterator iter(descriptors, PcDescriptorsLayout::kAnyKind); + while (iter.MoveNext()) { + const intptr_t current_try_index = iter.TryIndex(); + if ((iter.PcOffset() == pc_offset) && (current_try_index != -1)) { + try_index = current_try_index; + break; } } if (try_index == -1) { @@ -514,13 +429,6 @@ bool StackFrame::FindExceptionHandler(Thread* thread, } TokenPosition StackFrame::GetTokenPos() const { - if (is_interpreted()) { - const Bytecode& bytecode = Bytecode::Handle(LookupDartBytecode()); - if (bytecode.IsNull()) { - return TokenPosition::kNoSource; // Stub frames do not have token_pos. - } - return bytecode.GetTokenIndexOfPC(pc()); - } const Code& code = Code::Handle(LookupDartCode()); if (code.IsNull()) { return TokenPosition::kNoSource; // Stub frames do not have token_pos. @@ -542,9 +450,6 @@ bool StackFrame::IsValid() const { if (IsEntryFrame() || IsExitFrame() || IsStubFrame()) { return true; } - if (is_interpreted()) { - return (LookupDartBytecode() != Bytecode::null()); - } return (LookupDartCode() != Code::null()); } @@ -565,25 +470,16 @@ void StackFrameIterator::SetupLastExitFrameData() { frames_.fp_ = exit_marker; frames_.sp_ = 0; frames_.pc_ = 0; - if (FLAG_enable_interpreter) { - frames_.CheckIfInterpreted(exit_marker); - } frames_.Unpoison(); } void StackFrameIterator::SetupNextExitFrameData() { ASSERT(entry_.fp() != 0); - uword exit_address = - entry_.fp() + ((entry_.is_interpreted() ? kKBCExitLinkSlotFromEntryFp - : kExitLinkSlotFromEntryFp) * - kWordSize); + uword exit_address = entry_.fp() + (kExitLinkSlotFromEntryFp * kWordSize); uword exit_marker = *reinterpret_cast(exit_address); frames_.fp_ = exit_marker; frames_.sp_ = 0; frames_.pc_ = 0; - if (FLAG_enable_interpreter) { - frames_.CheckIfInterpreted(exit_marker); - } frames_.Unpoison(); } @@ -616,9 +512,6 @@ StackFrameIterator::StackFrameIterator(uword last_fp, frames_.fp_ = last_fp; frames_.sp_ = 0; frames_.pc_ = 0; - if (FLAG_enable_interpreter) { - frames_.CheckIfInterpreted(last_fp); - } frames_.Unpoison(); } @@ -639,9 +532,6 @@ StackFrameIterator::StackFrameIterator(uword fp, frames_.fp_ = fp; frames_.sp_ = sp; frames_.pc_ = pc; - if (FLAG_enable_interpreter) { - frames_.CheckIfInterpreted(fp); - } frames_.Unpoison(); } @@ -666,10 +556,8 @@ StackFrame* StackFrameIterator::NextFrame() { // Iteration starts from an exit frame given by its fp. current_frame_ = NextExitFrame(); } else if (*(reinterpret_cast( - frames_.fp_ + - ((frames_.is_interpreted() ? kKBCSavedCallerFpSlotFromFp - : kSavedCallerFpSlotFromFp) * - kWordSize))) == 0) { + frames_.fp_ + (kSavedCallerFpSlotFromFp * kWordSize))) == + 0) { // Iteration starts from an entry frame given by its fp, sp, and pc. current_frame_ = NextEntryFrame(); } else { @@ -699,17 +587,6 @@ StackFrame* StackFrameIterator::NextFrame() { return current_frame_; } -void StackFrameIterator::FrameSetIterator::CheckIfInterpreted( - uword exit_marker) { -#if !defined(DART_PRECOMPILED_RUNTIME) - // TODO(regis): We should rely on a new thread vm_tag to identify an - // interpreter frame and not need the HasFrame() method. - ASSERT(FLAG_enable_interpreter); - Interpreter* interpreter = thread_->interpreter(); - is_interpreted_ = (interpreter != NULL) && interpreter->HasFrame(exit_marker); -#endif // !defined(DART_PRECOMPILED_RUNTIME) -} - // Tell MemorySanitizer that generated code initializes part of the stack. void StackFrameIterator::FrameSetIterator::Unpoison() { // When using a simulator, all writes to the stack happened from MSAN @@ -719,7 +596,7 @@ void StackFrameIterator::FrameSetIterator::Unpoison() { #if !defined(USING_SIMULATOR) if (fp_ == 0) return; // Note that Thread::os_thread_ is cleared when the thread is descheduled. - ASSERT(is_interpreted_ || (thread_->os_thread() == nullptr) || + ASSERT((thread_->os_thread() == nullptr) || ((thread_->os_thread()->stack_limit() < fp_) && (thread_->os_thread()->stack_base() > fp_))); uword lower; @@ -742,12 +619,10 @@ StackFrame* StackFrameIterator::FrameSetIterator::NextFrame(bool validate) { frame->sp_ = sp_; frame->fp_ = fp_; frame->pc_ = pc_; - frame->is_interpreted_ = is_interpreted_; sp_ = frame->GetCallerSp(); fp_ = frame->GetCallerFp(); pc_ = frame->GetCallerPc(); Unpoison(); - ASSERT(is_interpreted_ == frame->is_interpreted_); ASSERT(!validate || frame->IsValid()); return frame; } @@ -756,12 +631,10 @@ ExitFrame* StackFrameIterator::NextExitFrame() { exit_.sp_ = frames_.sp_; exit_.fp_ = frames_.fp_; exit_.pc_ = frames_.pc_; - exit_.is_interpreted_ = frames_.is_interpreted_; frames_.sp_ = exit_.GetCallerSp(); frames_.fp_ = exit_.GetCallerFp(); frames_.pc_ = exit_.GetCallerPc(); frames_.Unpoison(); - ASSERT(frames_.is_interpreted_ == exit_.is_interpreted_); ASSERT(!validate_ || exit_.IsValid()); return &exit_; } @@ -771,7 +644,6 @@ EntryFrame* StackFrameIterator::NextEntryFrame() { entry_.sp_ = frames_.sp_; entry_.fp_ = frames_.fp_; entry_.pc_ = frames_.pc_; - entry_.is_interpreted_ = frames_.is_interpreted_; SetupNextExitFrameData(); // Setup data for next exit frame in chain. ASSERT(!validate_ || entry_.IsValid()); return &entry_; diff --git a/runtime/vm/stack_frame.h b/runtime/vm/stack_frame.h index 048ca63904c..dff02794c60 100644 --- a/runtime/vm/stack_frame.h +++ b/runtime/vm/stack_frame.h @@ -7,9 +7,7 @@ #include "vm/allocation.h" #include "vm/frame_layout.h" -#include "vm/interpreter.h" #include "vm/object.h" -#include "vm/stack_frame_kbc.h" #include "vm/stub_code.h" #if defined(TARGET_ARCH_IA32) @@ -44,7 +42,6 @@ class StackFrame : public ValueObject { // The pool pointer is not implemented on all architectures. static int SavedCallerPpSlotFromFp() { - // Never called on an interpreter frame. if (runtime_frame_layout.saved_caller_pp_from_fp != kSavedCallerFpSlotFromFp) { return runtime_frame_layout.saved_caller_pp_from_fp; @@ -54,37 +51,30 @@ class StackFrame : public ValueObject { } bool IsMarkedForLazyDeopt() const { - ASSERT(!is_interpreted()); uword raw_pc = *reinterpret_cast(sp() + (kSavedPcSlotFromSp * kWordSize)); return raw_pc == StubCode::DeoptimizeLazyFromReturn().EntryPoint(); } void MarkForLazyDeopt() { - ASSERT(!is_interpreted()); set_pc(StubCode::DeoptimizeLazyFromReturn().EntryPoint()); } void UnmarkForLazyDeopt() { // If this frame was marked for lazy deopt, pc_ was computed to be the // original return address using the pending deopts table in GetCallerPc. // Write this value back into the frame. - ASSERT(!is_interpreted()); uword original_pc = pc(); ASSERT(original_pc != StubCode::DeoptimizeLazyFromReturn().EntryPoint()); set_pc(original_pc); } void set_pc(uword value) { - *reinterpret_cast(sp() + ((is_interpreted() ? kKBCSavedPcSlotFromSp - : kSavedPcSlotFromSp) * - kWordSize)) = value; + *reinterpret_cast(sp() + (kSavedPcSlotFromSp * kWordSize)) = value; pc_ = value; } void set_pc_marker(CodePtr code) { *reinterpret_cast( - fp() + ((is_interpreted() ? kKBCPcMarkerSlotFromFp - : runtime_frame_layout.code_from_fp) * - kWordSize)) = code; + fp() + (runtime_frame_layout.code_from_fp * kWordSize)) = code; } // Visit objects in the frame. @@ -110,11 +100,8 @@ class StackFrame : public ValueObject { virtual bool IsEntryFrame() const { return false; } virtual bool IsExitFrame() const { return false; } - virtual bool is_interpreted() const { return is_interpreted_; } - FunctionPtr LookupDartFunction() const; CodePtr LookupDartCode() const; - BytecodePtr LookupDartBytecode() const; bool FindExceptionHandler(Thread* thread, uword* handler_pc, bool* needs_stacktrace, @@ -125,15 +112,11 @@ class StackFrame : public ValueObject { static void DumpCurrentTrace(); - uword GetCallerSp() const { - return fp() + - ((is_interpreted() ? kKBCCallerSpSlotFromFp : kCallerSpSlotFromFp) * - kWordSize); - } + uword GetCallerSp() const { return fp() + (kCallerSpSlotFromFp * kWordSize); } protected: explicit StackFrame(Thread* thread) - : fp_(0), sp_(0), pc_(0), thread_(thread), is_interpreted_(false) {} + : fp_(0), sp_(0), pc_(0), thread_(thread) {} // Name of the frame, used for generic frame printing functionality. virtual const char* GetName() const { @@ -149,20 +132,15 @@ class StackFrame : public ValueObject { private: CodePtr GetCodeObject() const; - BytecodePtr GetBytecodeObject() const; uword GetCallerFp() const { - return *(reinterpret_cast( - fp() + ((is_interpreted() ? kKBCSavedCallerFpSlotFromFp - : kSavedCallerFpSlotFromFp) * - kWordSize))); + return *(reinterpret_cast(fp() + + (kSavedCallerFpSlotFromFp * kWordSize))); } uword GetCallerPc() const { uword raw_pc = *(reinterpret_cast( - fp() + ((is_interpreted() ? kKBCSavedCallerPcSlotFromFp - : kSavedCallerPcSlotFromFp) * - kWordSize))); + fp() + (kSavedCallerPcSlotFromFp * kWordSize))); ASSERT(raw_pc != StubCode::DeoptimizeLazyFromThrow().EntryPoint()); if (raw_pc == StubCode::DeoptimizeLazyFromReturn().EntryPoint()) { return isolate_group()->FindPendingDeoptAtSafepoint(GetCallerFp()); @@ -174,7 +152,6 @@ class StackFrame : public ValueObject { uword sp_; uword pc_; Thread* thread_; - bool is_interpreted_; // The iterators FrameSetIterator and StackFrameIterator set the private // fields fp_ and sp_ when they return the respective frame objects. @@ -210,9 +187,7 @@ class ExitFrame : public StackFrame { // dart code. class EntryFrame : public StackFrame { public: - bool IsValid() const { - return StubCode::InInvocationStub(pc(), is_interpreted()); - } + bool IsValid() const { return StubCode::InInvocationStub(pc()); } bool IsDartFrame(bool validate = true) const { return false; } bool IsStubFrame() const { return false; } bool IsEntryFrame() const { return true; } @@ -279,11 +254,9 @@ class StackFrameIterator : public ValueObject { if (fp_ == 0) { return false; } - const uword pc = *(reinterpret_cast( - sp_ + - ((is_interpreted() ? kKBCSavedPcSlotFromSp : kSavedPcSlotFromSp) * - kWordSize))); - return !StubCode::InInvocationStub(pc, is_interpreted()); + const uword pc = + *(reinterpret_cast(sp_ + (kSavedPcSlotFromSp * kWordSize))); + return !StubCode::InInvocationStub(pc); } // Get next non entry/exit frame in the set (assumes a next frame exists). @@ -291,14 +264,7 @@ class StackFrameIterator : public ValueObject { private: explicit FrameSetIterator(Thread* thread) - : fp_(0), - sp_(0), - pc_(0), - stack_frame_(thread), - thread_(thread), - is_interpreted_(false) {} - bool is_interpreted() const { return is_interpreted_; } - void CheckIfInterpreted(uword exit_marker); + : fp_(0), sp_(0), pc_(0), stack_frame_(thread), thread_(thread) {} void Unpoison(); uword fp_; @@ -306,7 +272,6 @@ class StackFrameIterator : public ValueObject { uword pc_; StackFrame stack_frame_; // Singleton frame returned by NextFrame(). Thread* thread_; - bool is_interpreted_; friend class StackFrameIterator; DISALLOW_COPY_AND_ASSIGN(FrameSetIterator); @@ -327,8 +292,6 @@ class StackFrameIterator : public ValueObject { void SetupLastExitFrameData(); void SetupNextExitFrameData(); - void CheckInterpreterExitFrame(uword exit_marker); - bool validate_; // Validate each frame as we traverse the frames. EntryFrame entry_; // Singleton entry frame returned by NextEntryFrame(). ExitFrame exit_; // Singleton exit frame returned by NextExitFrame(). @@ -453,12 +416,6 @@ DART_FORCE_INLINE static bool IsCalleeFrameOf(uword fp, uword other_fp) { return other_fp < fp; } -// Both fp and other_fp are bytecode frame pointers. -DART_FORCE_INLINE static bool IsBytecodeCalleeFrameOf(uword fp, - uword other_fp) { - return other_fp > fp; -} - // Value for stack limit that is used to cause an interrupt. static const uword kInterruptStackLimit = ~static_cast(0); diff --git a/runtime/vm/stack_frame_kbc.h b/runtime/vm/stack_frame_kbc.h deleted file mode 100644 index 6af9a3a4bb7..00000000000 --- a/runtime/vm/stack_frame_kbc.h +++ /dev/null @@ -1,64 +0,0 @@ -// Copyright (c) 2018, the Dart project authors. Please see the AUTHORS file -// for details. All rights reserved. Use of this source code is governed by a -// BSD-style license that can be found in the LICENSE file. - -#ifndef RUNTIME_VM_STACK_FRAME_KBC_H_ -#define RUNTIME_VM_STACK_FRAME_KBC_H_ - -#include "platform/globals.h" - -namespace dart { - -/* Kernel Bytecode Frame Layout - -IMPORTANT: KBC stack is growing upwards which is different from all other -architectures. This enables efficient addressing for locals via unsigned index. - - | | <- TOS -Callee frame | ... | - | saved FP | (FP of current frame) - | saved PC | (PC of current frame) - | code object | - | function object | - +--------------------+ -Current frame | ... T| <- SP of current frame - | ... T| - | first local T| <- FP of current frame - | caller's FP | - | caller's PC | - | code object T| (current frame's code object) - | function object T| (current frame's function object) - +--------------------+ -Caller frame | last parameter | <- SP of caller frame - | ... | - - T against a slot indicates it needs to be traversed during GC. -*/ - -static const int kKBCDartFrameFixedSize = 4; // Function, Code, PC, FP -static const int kKBCSavedPcSlotFromSp = 3; - -static const int kKBCFirstObjectSlotFromFp = -4; // Used by GC. -static const int kKBCLastFixedObjectSlotFromFp = -3; - -static const int kKBCSavedCallerFpSlotFromFp = -1; -static const int kKBCSavedCallerPcSlotFromFp = -2; -static const int kKBCCallerSpSlotFromFp = -kKBCDartFrameFixedSize - 1; -static const int kKBCPcMarkerSlotFromFp = -3; -static const int kKBCFunctionSlotFromFp = -4; -static const int kKBCParamEndSlotFromFp = 4; - -// Entry and exit frame layout. -static const int kKBCEntrySavedSlots = 3; -static const int kKBCExitLinkSlotFromEntryFp = 0; -static const int kKBCSavedArgDescSlotFromEntryFp = 1; -static const int kKBCSavedPpSlotFromEntryFp = 2; - -// Value for stack limit that is used to cause an interrupt. -// Note that on KBC stack is growing upwards so interrupt limit is 0 unlike -// on all other architectures. -static const uword kKBCInterruptStackLimit = 0; - -} // namespace dart - -#endif // RUNTIME_VM_STACK_FRAME_KBC_H_ diff --git a/runtime/vm/stack_frame_test.cc b/runtime/vm/stack_frame_test.cc index b20e4b822ac..8ed14b95af6 100644 --- a/runtime/vm/stack_frame_test.cc +++ b/runtime/vm/stack_frame_test.cc @@ -259,45 +259,7 @@ TEST_CASE(ValidateNoSuchMethodStackFrameIteration) { // The true stack depends on which strategy we are using for noSuchMethod. The // stacktrace as seen by Dart is the same either way because dispatcher // methods are marked invisible. - if (FLAG_enable_interpreter) { - kScriptChars = - "class StackFrame {" - " static equals(var obj1, var obj2) native \"StackFrame_equals\";" - " static int frameCount() native \"StackFrame_frameCount\";" - " static int dartFrameCount() native \"StackFrame_dartFrameCount\";" - " static validateFrame(int index," - " String name) native " - "\"StackFrame_validateFrame\";" - "} " - "class StackFrame2Test {" - " StackFrame2Test() {}" - " noSuchMethod(Invocation im) {" - " /* We should have 8 general frames and 4 dart frames as follows:" - " * exit frame" - " * dart frame corresponding to StackFrame.frameCount" - " * dart frame corresponding to StackFrame2Test.noSuchMethod" - " * entry frame" - " * exit frame" - " * dart frame for noSuchMethod dispatcher" - " * dart frame corresponding to StackFrame2Test.testMain" - " * entry frame" - " */" - " StackFrame.equals(8, StackFrame.frameCount());" - " StackFrame.equals(4, StackFrame.dartFrameCount());" - " StackFrame.validateFrame(0, \"StackFrame_validateFrame\");" - " StackFrame.validateFrame(1, \"StackFrame2Test_noSuchMethod\");" - " StackFrame.validateFrame(2, \"StackFrame2Test_foo\");" - " StackFrame.validateFrame(3, \"StackFrame2Test_testMain\");" - " return 5;" - " }" - " static testMain() {" - " /* Declare |obj| dynamic so that noSuchMethod can be" - " * called in strong mode. */" - " dynamic obj = new StackFrame2Test();" - " StackFrame.equals(5, obj.foo(101, 202));" - " }" - "}"; - } else if (FLAG_lazy_dispatchers) { + if (FLAG_lazy_dispatchers) { kScriptChars = "class StackFrame {" " static equals(var obj1, var obj2) native \"StackFrame_equals\";" diff --git a/runtime/vm/stack_trace.cc b/runtime/vm/stack_trace.cc index 84459ad16b0..adb9c8bfede 100644 --- a/runtime/vm/stack_trace.cc +++ b/runtime/vm/stack_trace.cc @@ -8,10 +8,6 @@ #include "vm/stack_frame.h" #include "vm/symbols.h" -#if !defined(DART_PRECOMPILED_RUNTIME) -#include "vm/compiler/frontend/bytecode_reader.h" -#endif // !defined(DART_PRECOMPILED_RUNTIME) - namespace dart { // Keep in sync with @@ -46,29 +42,6 @@ intptr_t FindPcOffset(const PcDescriptors& pc_descs, intptr_t yield_index) { UNREACHABLE(); // If we cannot find it we have a bug. } -#if !defined(DART_PRECOMPILED_RUNTIME) -intptr_t FindPcOffset(const Bytecode& bytecode, intptr_t yield_index) { - if (yield_index == PcDescriptorsLayout::kInvalidYieldIndex) { - return 0; - } - if (!bytecode.HasSourcePositions()) { - return 0; - } - intptr_t last_yield_point = 0; - kernel::BytecodeSourcePositionsIterator iter(Thread::Current()->zone(), - bytecode); - while (iter.MoveNext()) { - if (iter.IsYieldPoint()) { - last_yield_point++; - } - if (last_yield_point == yield_index) { - return iter.PcOffset(); - } - } - UNREACHABLE(); // If we cannot find it we have a bug. -} -#endif - // Instance caches library and field references. // This way we don't have to do the look-ups for every frame in the stack. CallerClosureFinder::CallerClosureFinder(Zone* zone) @@ -301,8 +274,7 @@ bool CallerClosureFinder::IsRunningAsync(const Closure& receiver_closure) { } ClosurePtr StackTraceUtils::FindClosureInFrame(ObjectPtr* last_object_in_caller, - const Function& function, - bool is_interpreted) { + const Function& function) { NoSafepointScope nsp; ASSERT(!function.IsNull()); @@ -317,8 +289,7 @@ ClosurePtr StackTraceUtils::FindClosureInFrame(ObjectPtr* last_object_in_caller, const intptr_t kNumClosureAndArgs = 4; auto& closure = Closure::Handle(); for (intptr_t i = 0; i < kNumClosureAndArgs; i++) { - // KBC builds the stack upwards instead of the usual downwards stack. - ObjectPtr arg = last_object_in_caller[(is_interpreted ? -i : i)]; + ObjectPtr arg = last_object_in_caller[i]; if (arg->IsHeapObject() && arg->GetClassId() == kClosureCid) { closure = Closure::RawCast(arg); if (closure.function() == function.raw()) { @@ -351,7 +322,6 @@ void StackTraceUtils::CollectFramesLazy( auto& function = Function::Handle(zone); auto& code = Code::Handle(zone); - auto& bytecode = Bytecode::Handle(zone); auto& offset = Smi::Handle(zone); auto& closure = Closure::Handle(zone); @@ -365,32 +335,15 @@ void StackTraceUtils::CollectFramesLazy( continue; } - if (frame->is_interpreted()) { - bytecode = frame->LookupDartBytecode(); - ASSERT(!bytecode.IsNull()); - function = bytecode.function(); - if (function.IsNull()) { - continue; - } - RELEASE_ASSERT(function.raw() == frame->LookupDartFunction()); - } else { - function = frame->LookupDartFunction(); - } + function = frame->LookupDartFunction(); // Add the current synchronous frame. - if (frame->is_interpreted()) { - code_array.Add(bytecode); - const intptr_t pc_offset = frame->pc() - bytecode.PayloadStart(); - ASSERT(pc_offset > 0 && pc_offset <= bytecode.Size()); - offset = Smi::New(pc_offset); - } else { - code = frame->LookupDartCode(); - ASSERT(function.raw() == code.function()); - code_array.Add(code); - const intptr_t pc_offset = frame->pc() - code.PayloadStart(); - ASSERT(pc_offset > 0 && pc_offset <= code.Size()); - offset = Smi::New(pc_offset); - } + code = frame->LookupDartCode(); + ASSERT(function.raw() == code.function()); + code_array.Add(code); + const intptr_t pc_offset = frame->pc() - code.PayloadStart(); + ASSERT(pc_offset > 0 && pc_offset <= code.Size()); + offset = Smi::New(pc_offset); pc_offset_array.Add(offset); if (on_sync_frames != nullptr) { (*on_sync_frames)(frame); @@ -411,8 +364,7 @@ void StackTraceUtils::CollectFramesLazy( // through the yields. ObjectPtr* last_caller_obj = reinterpret_cast(frame->GetCallerSp()); - closure = FindClosureInFrame(last_caller_obj, function, - frame->is_interpreted()); + closure = FindClosureInFrame(last_caller_obj, function); // If this async function hasn't yielded yet, we're still dealing with a // normal stack. Continue to next frame as usual. @@ -434,18 +386,10 @@ void StackTraceUtils::CollectFramesLazy( closure = caller_closure_finder.FindCaller(closure)) { function = closure.function(); // In hot-reload-test-mode we sometimes have to do this: - if (!function.HasCode() && !function.HasBytecode()) { + if (!function.HasCode()) { function.EnsureHasCode(); } - if (function.HasBytecode()) { -#if !defined(DART_PRECOMPILED_RUNTIME) - bytecode = function.bytecode(); - code_array.Add(bytecode); - offset = Smi::New(FindPcOffset(bytecode, GetYieldIndex(closure))); -#else - UNREACHABLE(); -#endif // !defined(DART_PRECOMPILED_RUNTIME) - } else if (function.HasCode()) { + if (function.HasCode()) { code = function.CurrentCode(); code_array.Add(code); pc_descs = code.pc_descriptors(); @@ -485,7 +429,6 @@ intptr_t StackTraceUtils::CountFrames(Thread* thread, ASSERT(frame != NULL); // We expect to find a dart invocation frame. Function& function = Function::Handle(zone); Code& code = Code::Handle(zone); - Bytecode& bytecode = Bytecode::Handle(zone); String& function_name = String::Handle(zone); const bool async_function_is_null = async_function.IsNull(); int sync_async_gap_frames = -1; @@ -499,14 +442,8 @@ intptr_t StackTraceUtils::CountFrames(Thread* thread, skip_frames--; continue; } - if (frame->is_interpreted()) { - bytecode = frame->LookupDartBytecode(); - function = bytecode.function(); - if (function.IsNull()) continue; - } else { - code = frame->LookupDartCode(); - function = code.function(); - } + code = frame->LookupDartCode(); + function = code.function(); const bool function_is_null = function.IsNull(); if (!function_is_null && sync_async_gap_frames > 0) { function_name = function.QualifiedScrubbedName(); @@ -539,9 +476,7 @@ intptr_t StackTraceUtils::CollectFrames(Thread* thread, StackFrameIterator::kNoCrossThreadIteration); StackFrame* frame = frames.NextFrame(); ASSERT(frame != NULL); // We expect to find a dart invocation frame. - Function& function = Function::Handle(zone); Code& code = Code::Handle(zone); - Bytecode& bytecode = Bytecode::Handle(zone); Smi& offset = Smi::Handle(zone); intptr_t collected_frames_count = 0; for (; (frame != NULL) && (collected_frames_count < count); @@ -553,19 +488,9 @@ intptr_t StackTraceUtils::CollectFrames(Thread* thread, skip_frames--; continue; } - if (frame->is_interpreted()) { - bytecode = frame->LookupDartBytecode(); - function = bytecode.function(); - if (function.IsNull()) { - continue; - } - offset = Smi::New(frame->pc() - bytecode.PayloadStart()); - code_array.SetAt(array_offset, bytecode); - } else { - code = frame->LookupDartCode(); - offset = Smi::New(frame->pc() - code.PayloadStart()); - code_array.SetAt(array_offset, code); - } + code = frame->LookupDartCode(); + offset = Smi::New(frame->pc() - code.PayloadStart()); + code_array.SetAt(array_offset, code); pc_offset_array.SetAt(array_offset, offset); array_offset++; collected_frames_count++; @@ -598,12 +523,8 @@ intptr_t StackTraceUtils::ExtractAsyncStackTraceInfo( ASSERT(async_code_array->At(0) != Code::null()); ASSERT(async_code_array->At(0) == StubCode::AsynchronousGapMarker().raw()); const Object& code_object = Object::Handle(async_code_array->At(1)); - if (code_object.IsCode()) { - *async_function = Code::Cast(code_object).function(); - } else { - ASSERT(code_object.IsBytecode()); - *async_function = Bytecode::Cast(code_object).function(); - } + ASSERT(code_object.IsCode()); + *async_function = Code::Cast(code_object).function(); ASSERT(!async_function->IsNull()); ASSERT(async_function->IsAsyncFunction() || async_function->IsAsyncGenerator()); diff --git a/runtime/vm/stack_trace.h b/runtime/vm/stack_trace.h index 168482440b2..adfec68bd60 100644 --- a/runtime/vm/stack_trace.h +++ b/runtime/vm/stack_trace.h @@ -71,8 +71,7 @@ class StackTraceUtils : public AllStatic { public: // Find the async_op closure from the stack frame. static ClosurePtr FindClosureInFrame(ObjectPtr* last_object_in_caller, - const Function& function, - bool is_interpreted); + const Function& function); /// Collects all frames on the current stack until an async/async* frame is /// hit which has yielded before (i.e. is not in sync-async case). @@ -141,7 +140,7 @@ class StackTraceUtils : public AllStatic { // _AsyncAwaitCompleter.start (2) // (3) // - // Alternatively, for bytecode or optimized frames, we may see: + // Alternatively, for optimized frames, we may see: // __ (0) // _AsyncAwaitCompleter.start (1) // (2) diff --git a/runtime/vm/stub_code.cc b/runtime/vm/stub_code.cc index 92d8c6cc1b7..7f8f3a36ec7 100644 --- a/runtime/vm/stub_code.cc +++ b/runtime/vm/stub_code.cc @@ -10,7 +10,6 @@ #include "vm/compiler/assembler/disassembler.h" #include "vm/flags.h" #include "vm/heap/safepoint.h" -#include "vm/interpreter.h" #include "vm/object_store.h" #include "vm/snapshot.h" #include "vm/virtual_memory.h" @@ -26,8 +25,6 @@ namespace dart { DEFINE_FLAG(bool, disassemble_stubs, false, "Disassemble generated stubs."); DECLARE_FLAG(bool, precompiled_mode); -DECLARE_FLAG(bool, enable_interpreter); - StubCode::StubCodeEntry StubCode::entries_[kNumStubEntries] = { #if defined(DART_PRECOMPILED_RUNTIME) #define STUB_CODE_DECLARE(name) {nullptr, #name}, @@ -97,24 +94,8 @@ bool StubCode::HasBeenInitialized() { return entries_[kAsynchronousGapMarkerIndex].code != nullptr; } -bool StubCode::InInvocationStub(uword pc, bool is_interpreted_frame) { +bool StubCode::InInvocationStub(uword pc) { ASSERT(HasBeenInitialized()); -#if !defined(DART_PRECOMPILED_RUNTIME) - if (FLAG_enable_interpreter) { - if (is_interpreted_frame) { - // Recognize special marker set up by interpreter in entry frame. - return Interpreter::IsEntryFrameMarker( - reinterpret_cast(pc)); - } - { - uword entry = StubCode::InvokeDartCodeFromBytecode().EntryPoint(); - uword size = StubCode::InvokeDartCodeFromBytecodeSize(); - if ((pc >= entry) && (pc < (entry + size))) { - return true; - } - } - } -#endif // !defined(DART_PRECOMPILED_RUNTIME) uword entry = StubCode::InvokeDartCode().EntryPoint(); uword size = StubCode::InvokeDartCodeSize(); return (pc >= entry) && (pc < (entry + size)); diff --git a/runtime/vm/stub_code.h b/runtime/vm/stub_code.h index 016b8450c54..a946cd5881c 100644 --- a/runtime/vm/stub_code.h +++ b/runtime/vm/stub_code.h @@ -46,7 +46,7 @@ class StubCode : public AllStatic { // Check if specified pc is in the dart invocation stub used for // transitioning into dart code. - static bool InInvocationStub(uword pc, bool is_interpreted_frame); + static bool InInvocationStub(uword pc); // Check if the specified pc is in the jump to frame stub. static bool InJumpToFrameStub(uword pc); diff --git a/runtime/vm/stub_code_list.h b/runtime/vm/stub_code_list.h index baf6507a5e5..d12770187f4 100644 --- a/runtime/vm/stub_code_list.h +++ b/runtime/vm/stub_code_list.h @@ -42,7 +42,6 @@ namespace dart { V(CloneContext) \ V(CallToRuntime) \ V(LazyCompile) \ - V(InterpretCall) \ V(CallBootstrapNative) \ V(CallNoScopeNative) \ V(CallAutoScopeNative) \ @@ -50,7 +49,6 @@ namespace dart { V(CallStaticFunction) \ V(OptimizeFunction) \ V(InvokeDartCode) \ - V(InvokeDartCodeFromBytecode) \ V(DebugStepCheck) \ V(SwitchableCallMiss) \ V(MonomorphicSmiableCheck) \ diff --git a/runtime/vm/symbols.h b/runtime/vm/symbols.h index ba7cc2cd25f..40b953c06bb 100644 --- a/runtime/vm/symbols.h +++ b/runtime/vm/symbols.h @@ -40,7 +40,6 @@ class ObjectPointerVisitor; V(ByteData, "ByteData") \ V(ByteDataDot, "ByteData.") \ V(ByteDataDot_view, "ByteData._view") \ - V(Bytecode, "Bytecode") \ V(Call, "call") \ V(Cancel, "cancel") \ V(CastError, "_CastError") \ @@ -237,7 +236,6 @@ class ObjectPointerVisitor; V(Other, "other") \ V(OutOfMemoryError, "OutOfMemoryError") \ V(PackageScheme, "package:") \ - V(ParameterTypeCheck, "ParameterTypeCheck") \ V(Patch, "patch") \ V(PatchClass, "PatchClass") \ V(PcDescriptors, "PcDescriptors") \ diff --git a/runtime/vm/tagged_pointer.h b/runtime/vm/tagged_pointer.h index 6a8ce0379ec..703dfabd7ea 100644 --- a/runtime/vm/tagged_pointer.h +++ b/runtime/vm/tagged_pointer.h @@ -243,7 +243,6 @@ DEFINE_TAGGED_POINTER(Namespace, Object) DEFINE_TAGGED_POINTER(KernelProgramInfo, Object) DEFINE_TAGGED_POINTER(WeakSerializationReference, Object) DEFINE_TAGGED_POINTER(Code, Object) -DEFINE_TAGGED_POINTER(Bytecode, Object) DEFINE_TAGGED_POINTER(ObjectPool, Object) DEFINE_TAGGED_POINTER(Instructions, Object) DEFINE_TAGGED_POINTER(InstructionsSection, Object) @@ -254,7 +253,6 @@ DEFINE_TAGGED_POINTER(LocalVarDescriptors, Object) DEFINE_TAGGED_POINTER(ExceptionHandlers, Object) DEFINE_TAGGED_POINTER(Context, Object) DEFINE_TAGGED_POINTER(ContextScope, Object) -DEFINE_TAGGED_POINTER(ParameterTypeCheck, Object) DEFINE_TAGGED_POINTER(SingleTargetCache, Object) DEFINE_TAGGED_POINTER(UnlinkedCall, Object) DEFINE_TAGGED_POINTER(MonomorphicSmiableCall, Object) diff --git a/runtime/vm/tags.cc b/runtime/vm/tags.cc index ecc7d1879ff..8c48f2238b3 100644 --- a/runtime/vm/tags.cc +++ b/runtime/vm/tags.cc @@ -36,7 +36,7 @@ bool VMTag::IsNativeEntryTag(uword tag) { } bool VMTag::IsDartTag(uword id) { - return (id == kDartCompiledTagId) || (id == kDartInterpretedTagId); + return (id == kDartTagId); } bool VMTag::IsExitFrameTag(uword id) { diff --git a/runtime/vm/tags.h b/runtime/vm/tags.h index 4f3b665859e..e8d5919c902 100644 --- a/runtime/vm/tags.h +++ b/runtime/vm/tags.h @@ -18,13 +18,11 @@ class RuntimeEntry; V(Idle) /* isolate is idle and is_runnable() */ \ V(LoadWait) /* isolate is idle and !is_runnable() */ \ V(VM) /* Catch all */ \ - V(LoadBytecode) \ V(CompileOptimized) \ V(CompileUnoptimized) \ V(ClassLoading) \ V(CompileParseRegExp) \ - V(DartCompiled) \ - V(DartInterpreted) \ + V(Dart) \ V(GCNewSpace) \ V(GCOldSpace) \ V(GCIdle) \ diff --git a/runtime/vm/thread.cc b/runtime/vm/thread.cc index ecc51c5a058..e6b9b993d30 100644 --- a/runtime/vm/thread.cc +++ b/runtime/vm/thread.cc @@ -40,10 +40,6 @@ Thread::~Thread() { ASSERT(isolate_ == NULL); ASSERT(store_buffer_block_ == NULL); ASSERT(marking_stack_block_ == NULL); -#if !defined(DART_PRECOMPILED_RUNTIME) - delete interpreter_; - interpreter_ = nullptr; -#endif // There should be no top api scopes at this point. ASSERT(api_top_scope() == NULL); // Delete the resusable api scope if there is one. @@ -106,9 +102,6 @@ Thread::Thread(bool is_vm_isolate) REUSABLE_HANDLE_LIST(REUSABLE_HANDLE_SCOPE_INIT) #if defined(USING_SAFE_STACK) saved_safestack_limit_(0), -#endif -#if !defined(DART_PRECOMPILED_RUNTIME) - interpreter_(nullptr), #endif next_(NULL) { #if defined(SUPPORT_TIMELINE) @@ -681,12 +674,6 @@ void Thread::VisitObjectPointers(ObjectPointerVisitor* visitor, visitor->VisitPointer(reinterpret_cast(&async_stack_trace_)); visitor->VisitPointer(reinterpret_cast(&ffi_callback_code_)); -#if !defined(DART_PRECOMPILED_RUNTIME) - if (interpreter() != NULL) { - interpreter()->VisitObjectPointers(visitor); - } -#endif - // Visit the api local scope as it has all the api local handles. ApiLocalScope* scope = api_top_scope_; while (scope != NULL) { @@ -922,11 +909,6 @@ bool Thread::TopErrorHandlerIsSetJump() const { // False positives: simulator stack and native stack are unordered. return true; #else -#if !defined(DART_PRECOMPILED_RUNTIME) - // False positives: interpreter stack and native stack are unordered. - if ((interpreter_ != nullptr) && interpreter_->HasFrame(top_exit_frame_info_)) - return true; -#endif return reinterpret_cast(long_jump_base()) < top_exit_frame_info_; #endif } @@ -938,11 +920,6 @@ bool Thread::TopErrorHandlerIsExitFrame() const { // False positives: simulator stack and native stack are unordered. return true; #else -#if !defined(DART_PRECOMPILED_RUNTIME) - // False positives: interpreter stack and native stack are unordered. - if ((interpreter_ != nullptr) && interpreter_->HasFrame(top_exit_frame_info_)) - return true; -#endif return top_exit_frame_info_ < reinterpret_cast(long_jump_base()); #endif } diff --git a/runtime/vm/thread.h b/runtime/vm/thread.h index 34a65d0ed47..a4ecadb37d1 100644 --- a/runtime/vm/thread.h +++ b/runtime/vm/thread.h @@ -32,7 +32,6 @@ class Array; class CompilerState; class Class; class Code; -class Bytecode; class Error; class ExceptionHandlers; class Field; @@ -43,7 +42,6 @@ class HandleScope; class Heap; class HierarchyInfo; class Instance; -class Interpreter; class Isolate; class IsolateGroup; class Library; @@ -73,7 +71,6 @@ class Thread; V(Array) \ V(Class) \ V(Code) \ - V(Bytecode) \ V(Error) \ V(ExceptionHandlers) \ V(Field) \ @@ -98,8 +95,6 @@ class Thread; StubCode::FixAllocationStubTarget().raw(), nullptr) \ V(CodePtr, invoke_dart_code_stub_, StubCode::InvokeDartCode().raw(), \ nullptr) \ - V(CodePtr, invoke_dart_code_from_bytecode_stub_, \ - StubCode::InvokeDartCodeFromBytecode().raw(), nullptr) \ V(CodePtr, call_to_runtime_stub_, StubCode::CallToRuntime().raw(), nullptr) \ V(CodePtr, late_initialization_error_shared_without_fpu_regs_stub_, \ StubCode::LateInitializationErrorSharedWithoutFPURegs().raw(), nullptr) \ @@ -210,7 +205,6 @@ class Thread; NativeEntry::NoScopeNativeCallWrapperEntry(), 0) \ V(uword, auto_scope_native_wrapper_entry_point_, \ NativeEntry::AutoScopeNativeCallWrapperEntry(), 0) \ - V(uword, interpret_call_entry_point_, RuntimeEntry::InterpretCallEntry(), 0) \ V(StringPtr*, predefined_symbols_address_, Symbols::PredefinedAddress(), \ NULL) \ V(uword, double_nan_address_, reinterpret_cast(&double_nan_constant), \ @@ -472,11 +466,6 @@ class Thread : public ThreadState { type_usage_info_ = value; } -#if !defined(DART_PRECOMPILED_RUNTIME) - Interpreter* interpreter() const { return interpreter_; } - void set_interpreter(Interpreter* value) { interpreter_ = value; } -#endif - int32_t no_callback_scope_depth() const { return no_callback_scope_depth_; } void IncrementNoCallbackScopeDepth() { @@ -1031,10 +1020,6 @@ class Thread : public ThreadState { uword saved_safestack_limit_; #endif -#if !defined(DART_PRECOMPILED_RUNTIME) - Interpreter* interpreter_; -#endif - Thread* next_; // Used to chain the thread structures in an isolate. bool is_mutator_thread_ = false; @@ -1068,7 +1053,6 @@ class Thread : public ThreadState { #undef REUSABLE_FRIEND_DECLARATION friend class ApiZone; - friend class Interpreter; friend class InterruptChecker; friend class Isolate; friend class IsolateGroup; diff --git a/runtime/vm/thread_test.cc b/runtime/vm/thread_test.cc index 41e3374d765..4ea530806fe 100644 --- a/runtime/vm/thread_test.cc +++ b/runtime/vm/thread_test.cc @@ -14,8 +14,6 @@ namespace dart { -DECLARE_FLAG(bool, enable_interpreter); - VM_UNIT_TEST_CASE(Mutex) { // This unit test case needs a running isolate. TestCase::CreateTestIsolate(); @@ -638,7 +636,7 @@ TEST_CASE(SafepointTestDart) { #if defined(USING_SIMULATOR) const intptr_t kLoopCount = 12345678; #else - const intptr_t kLoopCount = FLAG_enable_interpreter ? 12345678 : 1234567890; + const intptr_t kLoopCount = 1234567890; #endif // defined(USING_SIMULATOR) char buffer[1024]; Utils::SNPrint(buffer, sizeof(buffer), diff --git a/runtime/vm/vm_sources.gni b/runtime/vm/vm_sources.gni index 83569d7bdad..a0e71ef1b98 100644 --- a/runtime/vm/vm_sources.gni +++ b/runtime/vm/vm_sources.gni @@ -41,7 +41,6 @@ vm_sources = [ "code_patcher_arm.cc", "code_patcher_arm64.cc", "code_patcher_ia32.cc", - "code_patcher_kbc.cc", "code_patcher_x64.cc", "compilation_trace.cc", "compilation_trace.h", @@ -52,8 +51,6 @@ vm_sources = [ "constants_base.h", "constants_ia32.cc", "constants_ia32.h", - "constants_kbc.cc", - "constants_kbc.h", "constants_x64.cc", "constants_x64.h", "cpu.h", @@ -85,7 +82,6 @@ vm_sources = [ "debugger_arm.cc", "debugger_arm64.cc", "debugger_ia32.cc", - "debugger_kbc.cc", "debugger_x64.cc", "deferred_objects.cc", "deferred_objects.h", @@ -130,12 +126,8 @@ vm_sources = [ "instructions_arm64.h", "instructions_ia32.cc", "instructions_ia32.h", - "instructions_kbc.cc", - "instructions_kbc.h", "instructions_x64.cc", "instructions_x64.h", - "interpreter.cc", - "interpreter.h", "intrusive_dlist.h", "isolate.cc", "isolate.h", @@ -298,7 +290,6 @@ vm_sources = [ "stack_frame_arm.h", "stack_frame_arm64.h", "stack_frame_ia32.h", - "stack_frame_kbc.h", "stack_frame_x64.h", "stack_trace.cc", "stack_trace.h",