mirror of
https://github.com/dart-lang/sdk
synced 2024-09-05 00:13:50 +00:00
![Ryan Macnak](/assets/img/avatar_default.png)
Currently we have things called XPtr which are not what you get from ptr().
Old world:
handle->raw() returns RawObject* (tagged)
raw_obj->ptr() returns RawObject* (untagged)
After 6fe15f6df9
:
handle->raw() returns ObjectPtr
obj_ptr->ptr() returns ObjectLayout*
New world:
handle->ptr() returns ObjectPtr
obj_ptr->untag() returns UntaggedObject*
TEST=ci
Change-Id: I6c7f34014cf20737607caaf84979838300d12df2
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/149367
Commit-Queue: Ryan Macnak <rmacnak@google.com>
Reviewed-by: Martin Kustermann <kustermann@google.com>
Reviewed-by: Siva Annamalai <asiva@google.com>
Reviewed-by: Vyacheslav Egorov <vegorov@google.com>
286 lines
8.6 KiB
C++
286 lines
8.6 KiB
C++
// Copyright (c) 2013, 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/dart_api_impl.h"
|
|
#include "vm/dart_api_state.h"
|
|
#include "vm/object.h"
|
|
#include "vm/symbols.h"
|
|
#include "vm/unit_test.h"
|
|
|
|
namespace dart {
|
|
|
|
FieldPtr LookupField(Dart_Handle library,
|
|
const char* class_name,
|
|
const char* field_name) {
|
|
LibraryPtr raw_library = Library::RawCast(Api::UnwrapHandle(library));
|
|
Library& lib = Library::ZoneHandle(raw_library);
|
|
const String& classname =
|
|
String::Handle(Symbols::New(Thread::Current(), class_name));
|
|
Class& cls = Class::Handle(lib.LookupClass(classname));
|
|
EXPECT(!cls.IsNull()); // No ambiguity error expected.
|
|
|
|
String& fieldname = String::Handle(String::New(field_name));
|
|
Field& field =
|
|
Field::ZoneHandle(cls.LookupInstanceFieldAllowPrivate(fieldname));
|
|
EXPECT(!field.IsNull());
|
|
return field.ptr();
|
|
}
|
|
|
|
TEST_CASE(GuardFieldSimpleTest) {
|
|
const char* script_chars =
|
|
"class A {\n"
|
|
" var f1 = 3.0;\n"
|
|
" dynamic f2 = 3;\n"
|
|
" var f3 = List<dynamic>.filled(4, null);\n"
|
|
" foo() {\n"
|
|
" f1 = f1 + f1;\n"
|
|
" }\n"
|
|
" bar() {\n"
|
|
" f2 = null;\n"
|
|
" f2 = 3.0;\n"
|
|
" }\n"
|
|
"}\n"
|
|
"\n"
|
|
"runFoo() {\n"
|
|
" var a = A();\n"
|
|
" for (int i = 0; i < 2000; i++) {\n"
|
|
" a.foo();\n"
|
|
" }\n"
|
|
"}\n"
|
|
"\n"
|
|
"runBar() {\n"
|
|
" var a = A();\n"
|
|
" for (int i = 0; i < 2000; i++) {\n"
|
|
" a.bar();\n"
|
|
" }\n"
|
|
"}\n"
|
|
"main() {\n"
|
|
" for (int i = 0; i < 100; i++) {\n"
|
|
" runFoo();\n"
|
|
" runBar();\n"
|
|
" }\n"
|
|
"}\n";
|
|
Dart_Handle lib = TestCase::LoadTestScript(script_chars, NULL);
|
|
Dart_Handle result = Dart_Invoke(lib, NewString("main"), 0, NULL);
|
|
EXPECT_VALID(result);
|
|
TransitionNativeToVM transition(thread);
|
|
Field& f1 = Field::ZoneHandle(LookupField(lib, "A", "f1"));
|
|
Field& f2 = Field::ZoneHandle(LookupField(lib, "A", "f2"));
|
|
Field& f3 = Field::ZoneHandle(LookupField(lib, "A", "f3"));
|
|
const intptr_t no_length = Field::kNoFixedLength;
|
|
EXPECT_EQ(no_length, f1.guarded_list_length());
|
|
EXPECT_EQ(kDoubleCid, f1.guarded_cid());
|
|
EXPECT_EQ(false, f1.is_nullable());
|
|
EXPECT_EQ(no_length, f2.guarded_list_length());
|
|
EXPECT_EQ(kDynamicCid, f2.guarded_cid());
|
|
EXPECT_EQ(true, f2.is_nullable());
|
|
EXPECT_EQ(no_length, f3.guarded_list_length());
|
|
}
|
|
|
|
TEST_CASE(GuardFieldFinalListTest) {
|
|
const char* script_chars =
|
|
"class A {\n"
|
|
" var f1 = 3.0;\n"
|
|
" dynamic f2 = 3;\n"
|
|
" final f3 = List<dynamic>.filled(4, null);\n"
|
|
" foo() {\n"
|
|
" f1 = f1 + f1;\n"
|
|
" }\n"
|
|
" bar() {\n"
|
|
" f2 = null;\n"
|
|
" f2 = 3.0;\n"
|
|
" }\n"
|
|
"}\n"
|
|
"\n"
|
|
"runFoo() {\n"
|
|
" var a = A();\n"
|
|
" for (int i = 0; i < 2000; i++) {\n"
|
|
" a.foo();\n"
|
|
" }\n"
|
|
"}\n"
|
|
"\n"
|
|
"runBar() {\n"
|
|
" var a = A();\n"
|
|
" for (int i = 0; i < 2000; i++) {\n"
|
|
" a.bar();\n"
|
|
" }\n"
|
|
"}\n"
|
|
"main() {\n"
|
|
" for (int i = 0; i < 100; i++) {\n"
|
|
" runFoo();\n"
|
|
" runBar();\n"
|
|
" }\n"
|
|
"}\n";
|
|
Dart_Handle lib = TestCase::LoadTestScript(script_chars, NULL);
|
|
Dart_Handle result = Dart_Invoke(lib, NewString("main"), 0, NULL);
|
|
EXPECT_VALID(result);
|
|
TransitionNativeToVM transition(thread);
|
|
Field& f1 = Field::ZoneHandle(LookupField(lib, "A", "f1"));
|
|
Field& f2 = Field::ZoneHandle(LookupField(lib, "A", "f2"));
|
|
Field& f3 = Field::ZoneHandle(LookupField(lib, "A", "f3"));
|
|
const intptr_t no_length = Field::kNoFixedLength;
|
|
EXPECT_EQ(no_length, f1.guarded_list_length());
|
|
EXPECT_EQ(kDoubleCid, f1.guarded_cid());
|
|
EXPECT_EQ(false, f1.is_nullable());
|
|
EXPECT_EQ(no_length, f2.guarded_list_length());
|
|
EXPECT_EQ(kDynamicCid, f2.guarded_cid());
|
|
EXPECT_EQ(true, f2.is_nullable());
|
|
EXPECT_EQ(4, f3.guarded_list_length());
|
|
EXPECT_EQ(kArrayCid, f3.guarded_cid());
|
|
EXPECT_EQ(false, f3.is_nullable());
|
|
}
|
|
|
|
TEST_CASE(GuardFieldFinalVariableLengthListTest) {
|
|
const char* script_chars =
|
|
"class A {\n"
|
|
" var f1 = 3.0;\n"
|
|
" dynamic f2 = 3;\n"
|
|
" final f3 = List.empty(growable: true);\n"
|
|
" foo() {\n"
|
|
" f1 = f1 + f1;\n"
|
|
" }\n"
|
|
" bar() {\n"
|
|
" f2 = null;\n"
|
|
" f2 = 3.0;\n"
|
|
" }\n"
|
|
"}\n"
|
|
"\n"
|
|
"runFoo() {\n"
|
|
" var a = A();\n"
|
|
" for (int i = 0; i < 2000; i++) {\n"
|
|
" a.foo();\n"
|
|
" }\n"
|
|
"}\n"
|
|
"\n"
|
|
"runBar() {\n"
|
|
" var a = A();\n"
|
|
" for (int i = 0; i < 2000; i++) {\n"
|
|
" a.bar();\n"
|
|
" }\n"
|
|
"}\n"
|
|
"main() {\n"
|
|
" for (int i = 0; i < 100; i++) {\n"
|
|
" runFoo();\n"
|
|
" runBar();\n"
|
|
" }\n"
|
|
"}\n";
|
|
Dart_Handle lib = TestCase::LoadTestScript(script_chars, NULL);
|
|
Dart_Handle result = Dart_Invoke(lib, NewString("main"), 0, NULL);
|
|
EXPECT_VALID(result);
|
|
TransitionNativeToVM transition(thread);
|
|
Field& f1 = Field::ZoneHandle(LookupField(lib, "A", "f1"));
|
|
Field& f2 = Field::ZoneHandle(LookupField(lib, "A", "f2"));
|
|
Field& f3 = Field::ZoneHandle(LookupField(lib, "A", "f3"));
|
|
const intptr_t no_length = Field::kNoFixedLength;
|
|
EXPECT_EQ(no_length, f1.guarded_list_length());
|
|
EXPECT_EQ(kDoubleCid, f1.guarded_cid());
|
|
EXPECT_EQ(false, f1.is_nullable());
|
|
EXPECT_EQ(no_length, f2.guarded_list_length());
|
|
EXPECT_EQ(kDynamicCid, f2.guarded_cid());
|
|
EXPECT_EQ(true, f2.is_nullable());
|
|
EXPECT_EQ(no_length, f3.guarded_list_length());
|
|
EXPECT_EQ(kGrowableObjectArrayCid, f3.guarded_cid());
|
|
EXPECT_EQ(false, f3.is_nullable());
|
|
}
|
|
|
|
TEST_CASE(GuardFieldConstructorTest) {
|
|
const char* script_chars =
|
|
"import 'dart:typed_data';\n"
|
|
"class A {\n"
|
|
" var f1 = 3.0;\n"
|
|
" dynamic f2 = 3;\n"
|
|
" final f3;\n"
|
|
" A(x) : f3 = x;\n"
|
|
" foo() {\n"
|
|
" f1 = f1 + f1;\n"
|
|
" }\n"
|
|
" bar() {\n"
|
|
" f2 = null;\n"
|
|
" f2 = 3.0;\n"
|
|
" }\n"
|
|
"}\n"
|
|
"\n"
|
|
"runFoo() {\n"
|
|
" var l = new Float32List(5);\n"
|
|
" for (int i = 0; i < 2000; i++) {\n"
|
|
" var a = new A(l);\n"
|
|
" a.foo();\n"
|
|
" }\n"
|
|
"}\n"
|
|
"\n"
|
|
"runBar() {\n"
|
|
" var l = new Float32List(5);\n"
|
|
" var a = new A(l);\n"
|
|
" for (int i = 0; i < 2000; i++) {\n"
|
|
" a.bar();\n"
|
|
" }\n"
|
|
"}\n"
|
|
"main() {\n"
|
|
" for (int i = 0; i < 100; i++) {\n"
|
|
" runFoo();\n"
|
|
" runBar();\n"
|
|
" }\n"
|
|
"}\n";
|
|
Dart_Handle lib = TestCase::LoadTestScript(script_chars, NULL);
|
|
Dart_Handle result = Dart_Invoke(lib, NewString("main"), 0, NULL);
|
|
EXPECT_VALID(result);
|
|
TransitionNativeToVM transition(thread);
|
|
Field& f1 = Field::ZoneHandle(LookupField(lib, "A", "f1"));
|
|
Field& f2 = Field::ZoneHandle(LookupField(lib, "A", "f2"));
|
|
Field& f3 = Field::ZoneHandle(LookupField(lib, "A", "f3"));
|
|
const intptr_t no_length = Field::kNoFixedLength;
|
|
EXPECT_EQ(no_length, f1.guarded_list_length());
|
|
EXPECT_EQ(kDoubleCid, f1.guarded_cid());
|
|
EXPECT_EQ(false, f1.is_nullable());
|
|
EXPECT_EQ(no_length, f2.guarded_list_length());
|
|
EXPECT_EQ(kDynamicCid, f2.guarded_cid());
|
|
EXPECT_EQ(true, f2.is_nullable());
|
|
const intptr_t length = 5;
|
|
EXPECT_EQ(length, f3.guarded_list_length());
|
|
EXPECT_EQ(kTypedDataFloat32ArrayCid, f3.guarded_cid());
|
|
EXPECT_EQ(false, f3.is_nullable());
|
|
}
|
|
|
|
TEST_CASE(GuardFieldConstructor2Test) {
|
|
const char* script_chars =
|
|
"import 'dart:typed_data';\n"
|
|
"class A {\n"
|
|
" final f3;\n"
|
|
" A(x) : f3 = x;\n"
|
|
" foo() {\n"
|
|
" }\n"
|
|
" bar() {\n"
|
|
" }\n"
|
|
"}\n"
|
|
"\n"
|
|
"runFoo() {\n"
|
|
" var l = new Float32List(5);\n"
|
|
" for (int i = 0; i < 2000; i++) {\n"
|
|
" var a = new A(l);\n"
|
|
" }\n"
|
|
"}\n"
|
|
"\n"
|
|
"runBar() {\n"
|
|
" var l = new Float32List(99);\n"
|
|
" var a = new A(l);\n"
|
|
"}\n"
|
|
"main() {\n"
|
|
" for (int i = 0; i < 100; i++) {\n"
|
|
" runFoo();\n"
|
|
" runBar();\n"
|
|
" }\n"
|
|
"}\n";
|
|
Dart_Handle lib = TestCase::LoadTestScript(script_chars, NULL);
|
|
Dart_Handle result = Dart_Invoke(lib, NewString("main"), 0, NULL);
|
|
EXPECT_VALID(result);
|
|
TransitionNativeToVM transition(thread);
|
|
Field& f3 = Field::ZoneHandle(LookupField(lib, "A", "f3"));
|
|
const intptr_t no_length = Field::kNoFixedLength;
|
|
EXPECT_EQ(no_length, f3.guarded_list_length());
|
|
EXPECT_EQ(kTypedDataFloat32ArrayCid, f3.guarded_cid());
|
|
EXPECT_EQ(false, f3.is_nullable());
|
|
}
|
|
|
|
} // namespace dart
|