-
Notifications
You must be signed in to change notification settings - Fork 68
Expand file tree
/
Copy pathtest_globals.cpp
More file actions
77 lines (60 loc) · 2.13 KB
/
Copy pathtest_globals.cpp
File metadata and controls
77 lines (60 loc) · 2.13 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
#include "assert.hpp"
#include <java/lang/System.hpp>
#include <java/lang/String.hpp>
#include <jvm/local_frame.hpp>
#include <jvm/global.hpp>
using namespace java::lang;
using namespace jvm;
global<String> g_str;
struct git_t
{
git_t()
{
g_str = jnew<String>("JVM has started up...");
System::get_out().println(g_str);
}
~git_t()
{
System::get_out().println("JVM is about to close down...");
g_str.set_null();
}
};
/* Just declare a wrapped instance at global scope, and it will
be constructed right after the JVM is initialized, and will
be deleted shortly before it is destroyed.
*/
global_init_enlist<git_t> git;
#define QBF "The quick brown fox jumped over the lazy dog."
void test_globals()
{
/* If the declaration of s1 doesn't use java::global (as in
the commented out version) then the assertion at the bottom
MAY cause an access violation. Unfortunately this depends
on the behaviour of the GC so it's unpredictable, making
bugs hard to catch. To see it here you might also need to
increase the number of loops to 100000 or more.
The rule is: if a reference needs to survive outside of
a local_frame, it must be wrapped with global<T>.
It should be noted that you cannot avoid this problem by
the clever idea of simply never declaring any local_frame
objects. Without them, local references never die and so
the objects referred to are never collected.
*/
global<String> s1;
// String s1; // substitute this "naked" version to trigger problems
const int loops = 1000; // May need to add some zeros
for (int n = 0; n < loops; n++)
{
{
// comment out the next line and memory consumption will explode
local_frame lf;
String s2(QBF QBF QBF QBF QBF);
String s3(QBF QBF QBF QBF QBF);
if (s1.is_null()) // store the first concatenation in s1
s1 = s2.concat(s3);
}
}
// By this point, the GC may have collected s1 if it is not global.
ASSERT_EQUAL(std::string, QBF QBF QBF QBF QBF QBF QBF QBF QBF QBF, s1);
}
REGISTER_TEST(test_globals);