mirror of
https://github.com/dart-lang/sdk
synced 2024-11-02 09:43:08 +00:00
Test tracing of string allocations
Also, fix a bug in string allocation tracing. R=rmacnak@google.com Review URL: https://codereview.chromium.org//1230063010 .
This commit is contained in:
parent
13a372eca0
commit
4da11ef37f
6 changed files with 167 additions and 3 deletions
|
@ -1763,7 +1763,7 @@ static void TryAllocateOnebyteString(Assembler* assembler,
|
|||
Label* failure) {
|
||||
const Register length_reg = R2;
|
||||
Label fail;
|
||||
|
||||
__ MaybeTraceAllocation(kOneByteStringCid, R0, failure);
|
||||
__ mov(R6, Operand(length_reg)); // Save the length register.
|
||||
// TODO(koda): Protect against negative length and overflow here.
|
||||
__ SmiUntag(length_reg);
|
||||
|
|
|
@ -1843,7 +1843,7 @@ static void TryAllocateOnebyteString(Assembler* assembler,
|
|||
Label* failure) {
|
||||
const Register length_reg = R2;
|
||||
Label fail;
|
||||
|
||||
__ MaybeTraceAllocation(kOneByteStringCid, R0, kNoPP, failure);
|
||||
__ mov(R6, length_reg); // Save the length register.
|
||||
// TODO(koda): Protect against negative length and overflow here.
|
||||
__ SmiUntag(length_reg);
|
||||
|
|
|
@ -1869,6 +1869,7 @@ static void TryAllocateOnebyteString(Assembler* assembler,
|
|||
Label* ok,
|
||||
Label* failure,
|
||||
Register length_reg) {
|
||||
__ MaybeTraceAllocation(kOneByteStringCid, EAX, failure, false);
|
||||
if (length_reg != EDI) {
|
||||
__ movl(EDI, length_reg);
|
||||
}
|
||||
|
|
|
@ -1883,7 +1883,7 @@ static void TryAllocateOnebyteString(Assembler* assembler,
|
|||
Label* ok,
|
||||
Label* failure) {
|
||||
const Register length_reg = T2;
|
||||
|
||||
__ MaybeTraceAllocation(kOneByteStringCid, V0, failure);
|
||||
__ mov(T6, length_reg); // Save the length register.
|
||||
// TODO(koda): Protect against negative length and overflow here.
|
||||
__ SmiUntag(length_reg);
|
||||
|
|
|
@ -1727,6 +1727,7 @@ static void TryAllocateOnebyteString(Assembler* assembler,
|
|||
Label* ok,
|
||||
Label* failure,
|
||||
Register length_reg) {
|
||||
__ MaybeTraceAllocation(kOneByteStringCid, failure, false);
|
||||
if (length_reg != RDI) {
|
||||
__ movq(RDI, length_reg);
|
||||
}
|
||||
|
|
|
@ -569,4 +569,166 @@ TEST_CASE(Profiler_TypedArrayAllocation) {
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
TEST_CASE(Profiler_StringAllocation) {
|
||||
const char* kScript = "String foo(String a, String b) => a + b;";
|
||||
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 Class& one_byte_string_class =
|
||||
Class::Handle(isolate->object_store()->one_byte_string_class());
|
||||
EXPECT(!one_byte_string_class.IsNull());
|
||||
|
||||
Dart_Handle args[2] = { NewString("a"), NewString("b"), };
|
||||
|
||||
Dart_Handle result = Dart_Invoke(lib, NewString("foo"), 2, &args[0]);
|
||||
EXPECT_VALID(result);
|
||||
|
||||
{
|
||||
StackZone zone(isolate);
|
||||
HANDLESCOPE(isolate);
|
||||
Profile profile(isolate);
|
||||
AllocationFilter filter(isolate, one_byte_string_class.id());
|
||||
profile.Build(&filter, Profile::kNoTags);
|
||||
// We should have no allocation samples.
|
||||
EXPECT_EQ(0, profile.sample_count());
|
||||
}
|
||||
|
||||
one_byte_string_class.SetTraceAllocation(true);
|
||||
result = Dart_Invoke(lib, NewString("foo"), 2, &args[0]);
|
||||
EXPECT_VALID(result);
|
||||
|
||||
{
|
||||
StackZone zone(isolate);
|
||||
HANDLESCOPE(isolate);
|
||||
Profile profile(isolate);
|
||||
AllocationFilter filter(isolate, one_byte_string_class.id());
|
||||
profile.Build(&filter, Profile::kNoTags);
|
||||
// We should still only have one allocation sample.
|
||||
EXPECT_EQ(1, profile.sample_count());
|
||||
ProfileTrieWalker walker(&profile);
|
||||
|
||||
walker.Reset(Profile::kExclusiveCode);
|
||||
EXPECT(walker.Down());
|
||||
EXPECT_STREQ("_StringBase.+", walker.CurrentName());
|
||||
EXPECT(walker.Down());
|
||||
EXPECT_STREQ("foo", walker.CurrentName());
|
||||
EXPECT(!walker.Down());
|
||||
}
|
||||
|
||||
one_byte_string_class.SetTraceAllocation(false);
|
||||
result = Dart_Invoke(lib, NewString("foo"), 2, &args[0]);
|
||||
EXPECT_VALID(result);
|
||||
|
||||
{
|
||||
StackZone zone(isolate);
|
||||
HANDLESCOPE(isolate);
|
||||
Profile profile(isolate);
|
||||
AllocationFilter filter(isolate, one_byte_string_class.id());
|
||||
profile.Build(&filter, Profile::kNoTags);
|
||||
// We should still only have one allocation sample.
|
||||
EXPECT_EQ(1, profile.sample_count());
|
||||
}
|
||||
|
||||
one_byte_string_class.SetTraceAllocation(true);
|
||||
result = Dart_Invoke(lib, NewString("foo"), 2, &args[0]);
|
||||
EXPECT_VALID(result);
|
||||
|
||||
{
|
||||
StackZone zone(isolate);
|
||||
HANDLESCOPE(isolate);
|
||||
Profile profile(isolate);
|
||||
AllocationFilter filter(isolate, one_byte_string_class.id());
|
||||
profile.Build(&filter, Profile::kNoTags);
|
||||
// We should now have two allocation samples.
|
||||
EXPECT_EQ(2, profile.sample_count());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
TEST_CASE(Profiler_StringInterpolation) {
|
||||
const char* kScript = "String foo(String a, String b) => '$a | $b';";
|
||||
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 Class& one_byte_string_class =
|
||||
Class::Handle(isolate->object_store()->one_byte_string_class());
|
||||
EXPECT(!one_byte_string_class.IsNull());
|
||||
|
||||
Dart_Handle args[2] = { NewString("a"), NewString("b"), };
|
||||
|
||||
Dart_Handle result = Dart_Invoke(lib, NewString("foo"), 2, &args[0]);
|
||||
EXPECT_VALID(result);
|
||||
|
||||
{
|
||||
StackZone zone(isolate);
|
||||
HANDLESCOPE(isolate);
|
||||
Profile profile(isolate);
|
||||
AllocationFilter filter(isolate, one_byte_string_class.id());
|
||||
profile.Build(&filter, Profile::kNoTags);
|
||||
// We should have no allocation samples.
|
||||
EXPECT_EQ(0, profile.sample_count());
|
||||
}
|
||||
|
||||
one_byte_string_class.SetTraceAllocation(true);
|
||||
result = Dart_Invoke(lib, NewString("foo"), 2, &args[0]);
|
||||
EXPECT_VALID(result);
|
||||
|
||||
{
|
||||
StackZone zone(isolate);
|
||||
HANDLESCOPE(isolate);
|
||||
Profile profile(isolate);
|
||||
AllocationFilter filter(isolate, one_byte_string_class.id());
|
||||
profile.Build(&filter, Profile::kNoTags);
|
||||
// We should still only have one allocation sample.
|
||||
EXPECT_EQ(1, profile.sample_count());
|
||||
ProfileTrieWalker walker(&profile);
|
||||
|
||||
walker.Reset(Profile::kExclusiveCode);
|
||||
EXPECT(walker.Down());
|
||||
EXPECT_STREQ("_OneByteString._allocate", walker.CurrentName());
|
||||
EXPECT(walker.Down());
|
||||
EXPECT_STREQ("_OneByteString._concatAll", walker.CurrentName());
|
||||
EXPECT(walker.Down());
|
||||
EXPECT_STREQ("_StringBase._interpolate", walker.CurrentName());
|
||||
EXPECT(walker.Down());
|
||||
EXPECT_STREQ("foo", walker.CurrentName());
|
||||
EXPECT(!walker.Down());
|
||||
}
|
||||
|
||||
one_byte_string_class.SetTraceAllocation(false);
|
||||
result = Dart_Invoke(lib, NewString("foo"), 2, &args[0]);
|
||||
EXPECT_VALID(result);
|
||||
|
||||
{
|
||||
StackZone zone(isolate);
|
||||
HANDLESCOPE(isolate);
|
||||
Profile profile(isolate);
|
||||
AllocationFilter filter(isolate, one_byte_string_class.id());
|
||||
profile.Build(&filter, Profile::kNoTags);
|
||||
// We should still only have one allocation sample.
|
||||
EXPECT_EQ(1, profile.sample_count());
|
||||
}
|
||||
|
||||
one_byte_string_class.SetTraceAllocation(true);
|
||||
result = Dart_Invoke(lib, NewString("foo"), 2, &args[0]);
|
||||
EXPECT_VALID(result);
|
||||
|
||||
{
|
||||
StackZone zone(isolate);
|
||||
HANDLESCOPE(isolate);
|
||||
Profile profile(isolate);
|
||||
AllocationFilter filter(isolate, one_byte_string_class.id());
|
||||
profile.Build(&filter, Profile::kNoTags);
|
||||
// We should now have two allocation samples.
|
||||
EXPECT_EQ(2, profile.sample_count());
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace dart
|
||||
|
|
Loading…
Reference in a new issue