OLD | NEW |
| (Empty) |
1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file | |
2 // for details. All rights reserved. Use of this source code is governed by a | |
3 // BSD-style license that can be found in the LICENSE file. | |
4 | |
5 #include <iostream> | |
6 #include <sstream> | |
7 #include <string> | |
8 #include "vm/dart_api_impl.h" | |
9 #include "vm/growable_array.h" | |
10 #include "vm/heap.h" | |
11 #include "vm/heap_trace.h" | |
12 #include "vm/unit_test.h" | |
13 | |
14 namespace dart { | |
15 | |
16 // only ia32 can run heap trace tests. | |
17 #if defined(TARGET_ARCH_IA32) | |
18 static std::stringstream* global_stream; | |
19 | |
20 static void* OpenTraceFile(const char* name) { | |
21 ASSERT(global_stream == NULL); | |
22 global_stream = new std::stringstream; | |
23 return reinterpret_cast<void*>(global_stream); | |
24 } | |
25 | |
26 | |
27 static void WriteToTraceFile(const void* data, intptr_t length, void* stream) { | |
28 ASSERT(stream == global_stream); | |
29 std::stringstream* sstream = reinterpret_cast<std::stringstream*>(stream); | |
30 sstream->write(reinterpret_cast<const char*>(data), length); | |
31 } | |
32 | |
33 | |
34 static void CloseTraceFile(void *stream) { | |
35 ASSERT(stream == global_stream); | |
36 global_stream = NULL; | |
37 delete reinterpret_cast<std::stringstream*>(stream); | |
38 } | |
39 | |
40 | |
41 bool DoesAllocationRecordExist(uword addr, const std::string& trace_string) { | |
42 const char* raw_trace = trace_string.c_str(); | |
43 for (size_t i = 0; i < trace_string.length(); ++i) { | |
44 if ((raw_trace[i] == 'A') && (i + 4 < trace_string.length())) { | |
45 const uword candidate_address = | |
46 *(reinterpret_cast<const uword*>(raw_trace + i + 1)); | |
47 if (candidate_address == addr) { | |
48 return true; | |
49 } | |
50 } | |
51 } | |
52 return false; | |
53 } | |
54 | |
55 | |
56 bool DoesSweepRecordExist(uword addr, const std::string& trace_string) { | |
57 const char* raw_trace = trace_string.c_str(); | |
58 for (size_t i = 0; i < trace_string.length(); ++i) { | |
59 if ((raw_trace[i] == 'S') && (i + 4 < trace_string.length())) { | |
60 const uword candidate_address = | |
61 *(reinterpret_cast<const uword*>(raw_trace + i + 1)); | |
62 if (candidate_address == addr) { | |
63 return true; | |
64 } | |
65 } | |
66 } | |
67 return false; | |
68 } | |
69 | |
70 | |
71 TEST_CASE(GCTraceAllocate) { | |
72 HeapTrace::InitOnce(OpenTraceFile, | |
73 WriteToTraceFile, | |
74 CloseTraceFile); | |
75 | |
76 Isolate* isolate = Isolate::Current(); | |
77 isolate->heap()->trace()->Init(isolate); | |
78 | |
79 const int kArrayLen = 5; | |
80 RawArray* raw_arr = Array::New(kArrayLen); | |
81 uword addr = RawObject::ToAddr(raw_arr); | |
82 | |
83 ASSERT(DoesAllocationRecordExist(addr, global_stream->str())); | |
84 } | |
85 | |
86 | |
87 TEST_CASE(GCTraceSweep) { | |
88 HeapTrace::InitOnce(OpenTraceFile, | |
89 WriteToTraceFile, | |
90 CloseTraceFile); | |
91 | |
92 Isolate* isolate = Isolate::Current(); | |
93 isolate->heap()->trace()->Init(isolate); | |
94 | |
95 const int kArrayLen = 5; | |
96 RawArray* raw_arr = Array::New(kArrayLen, Heap::kOld); | |
97 uword addr = RawObject::ToAddr(raw_arr); | |
98 | |
99 Isolate::Current()->heap()->CollectGarbage(Heap::kOld); | |
100 DoesSweepRecordExist(addr, global_stream->str()); | |
101 } | |
102 #endif | |
103 | |
104 } // namespace dart | |
OLD | NEW |