diff --git a/runtime/vm/intrinsifier_arm.cc b/runtime/vm/intrinsifier_arm.cc index 451b54f9d72..0c5ce2c3e3a 100644 --- a/runtime/vm/intrinsifier_arm.cc +++ b/runtime/vm/intrinsifier_arm.cc @@ -189,6 +189,7 @@ void Intrinsifier::GrowableArray_add(Assembler* assembler) { #define TYPED_ARRAY_ALLOCATION(type_name, cid, max_len, scale_shift) \ Label fall_through; \ const intptr_t kArrayLengthStackOffset = 0 * kWordSize; \ + __ MaybeTraceAllocation(cid, R2, &fall_through); \ __ ldr(R2, Address(SP, kArrayLengthStackOffset)); /* Array length. */ \ /* Check that length is a positive Smi. */ \ /* R2: requested array length argument. */ \ diff --git a/runtime/vm/intrinsifier_arm64.cc b/runtime/vm/intrinsifier_arm64.cc index dd46bcc6bd2..139608deb85 100644 --- a/runtime/vm/intrinsifier_arm64.cc +++ b/runtime/vm/intrinsifier_arm64.cc @@ -198,6 +198,7 @@ static int GetScaleFactor(intptr_t size) { #define TYPED_ARRAY_ALLOCATION(type_name, cid, max_len, scale_shift) \ Label fall_through; \ const intptr_t kArrayLengthStackOffset = 0 * kWordSize; \ + __ MaybeTraceAllocation(cid, R2, kNoPP, &fall_through); \ __ ldr(R2, Address(SP, kArrayLengthStackOffset)); /* Array length. */ \ /* Check that length is a positive Smi. */ \ /* R2: requested array length argument. */ \ diff --git a/runtime/vm/intrinsifier_ia32.cc b/runtime/vm/intrinsifier_ia32.cc index 2b15a71dd59..c8c5140145a 100644 --- a/runtime/vm/intrinsifier_ia32.cc +++ b/runtime/vm/intrinsifier_ia32.cc @@ -186,6 +186,7 @@ void Intrinsifier::GrowableArray_add(Assembler* assembler) { #define TYPED_ARRAY_ALLOCATION(type_name, cid, max_len, scale_factor) \ Label fall_through; \ const intptr_t kArrayLengthStackOffset = 1 * kWordSize; \ + __ MaybeTraceAllocation(cid, EDI, &fall_through, false); \ __ movl(EDI, Address(ESP, kArrayLengthStackOffset)); /* Array length. */ \ /* Check that length is a positive Smi. */ \ /* EDI: requested array length argument. */ \ diff --git a/runtime/vm/intrinsifier_mips.cc b/runtime/vm/intrinsifier_mips.cc index e20cbd0e632..cff0b62aadd 100644 --- a/runtime/vm/intrinsifier_mips.cc +++ b/runtime/vm/intrinsifier_mips.cc @@ -179,6 +179,7 @@ void Intrinsifier::GrowableArray_add(Assembler* assembler) { #define TYPED_ARRAY_ALLOCATION(type_name, cid, max_len, scale_shift) \ Label fall_through; \ const intptr_t kArrayLengthStackOffset = 0 * kWordSize; \ + __ MaybeTraceAllocation(cid, T2, &fall_through); \ __ lw(T2, Address(SP, kArrayLengthStackOffset)); /* Array length. */ \ /* Check that length is a positive Smi. */ \ /* T2: requested array length argument. */ \ diff --git a/runtime/vm/intrinsifier_x64.cc b/runtime/vm/intrinsifier_x64.cc index ad7c8b97b66..6cec20224cf 100644 --- a/runtime/vm/intrinsifier_x64.cc +++ b/runtime/vm/intrinsifier_x64.cc @@ -130,6 +130,7 @@ void Intrinsifier::GrowableArray_add(Assembler* assembler) { #define TYPED_ARRAY_ALLOCATION(type_name, cid, max_len, scale_factor) \ Label fall_through; \ const intptr_t kArrayLengthStackOffset = 1 * kWordSize; \ + __ MaybeTraceAllocation(cid, &fall_through, false); \ __ movq(RDI, Address(RSP, kArrayLengthStackOffset)); /* Array length. */ \ /* Check that length is a positive Smi. */ \ /* RDI: requested array length argument. */ \ diff --git a/runtime/vm/profiler_test.cc b/runtime/vm/profiler_test.cc index f24629ff796..9759876070c 100644 --- a/runtime/vm/profiler_test.cc +++ b/runtime/vm/profiler_test.cc @@ -103,7 +103,7 @@ TEST_CASE(Profiler_AllocationSampleTest) { static RawClass* GetClass(const Library& lib, const char* name) { const Class& cls = Class::Handle( - lib.LookupClass(String::Handle(Symbols::New(name)))); + lib.LookupClassAllowPrivate(String::Handle(Symbols::New(name)))); EXPECT(!cls.IsNull()); // No ambiguity error expected. return cls.raw(); } @@ -483,4 +483,62 @@ TEST_CASE(Profiler_ArrayAllocation) { } } + +TEST_CASE(Profiler_TypedArrayAllocation) { + const char* kScript = + "import 'dart:typed_data';\n" + "List foo() => new Float32List(4);\n"; + Dart_Handle lib = TestCase::LoadTestScript(kScript, NULL); + EXPECT_VALID(lib); + Library& root_library = Library::Handle(); + root_library ^= Api::UnwrapHandle(lib); + Isolate* isolate = Isolate::Current(); + + const Library& typed_data_library = + Library::Handle(isolate->object_store()->typed_data_library()); + + const Class& float32_list_class = + Class::Handle(GetClass(typed_data_library, "_Float32Array")); + EXPECT(!float32_list_class.IsNull()); + + Dart_Handle result = Dart_Invoke(lib, NewString("foo"), 0, NULL); + EXPECT_VALID(result); + + { + StackZone zone(isolate); + HANDLESCOPE(isolate); + Profile profile(isolate); + AllocationFilter filter(isolate, float32_list_class.id()); + profile.Build(&filter, Profile::kNoTags); + // We should have no allocation samples. + EXPECT_EQ(0, profile.sample_count()); + } + + float32_list_class.SetTraceAllocation(true); + result = Dart_Invoke(lib, NewString("foo"), 0, NULL); + EXPECT_VALID(result); + + { + StackZone zone(isolate); + HANDLESCOPE(isolate); + Profile profile(isolate); + AllocationFilter filter(isolate, float32_list_class.id()); + profile.Build(&filter, Profile::kNoTags); + // We should have one allocation sample. + EXPECT_EQ(1, profile.sample_count()); + ProfileTrieWalker walker(&profile); + + walker.Reset(Profile::kExclusiveCode); + EXPECT(walker.Down()); + EXPECT_STREQ("_Float32Array._new", walker.CurrentName()); + EXPECT(walker.Down()); + EXPECT_STREQ("_Float32Array._Float32Array", walker.CurrentName()); + EXPECT(walker.Down()); + EXPECT_STREQ("Float32List.Float32List", walker.CurrentName()); + EXPECT(walker.Down()); + EXPECT_STREQ("foo", walker.CurrentName()); + EXPECT(!walker.Down()); + } +} + } // namespace dart