annotate src/share/vm/utilities/events.cpp @ 1091:6aa7255741f3

6906727: UseCompressedOops: some card-marking fixes related to object arrays Summary: Introduced a new write_ref_array(HeapWords* start, size_t count) method that does the requisite MemRegion range calculation so (some of the) clients of the erstwhile write_ref_array(MemRegion mr) do not need to worry. This removed all external uses of array_size(), which was also simplified and made private. Asserts were added to catch other possible issues. Further, less essential, fixes stemming from this investigation are deferred to CR 6904516 (to follow shortly in hs17). Reviewed-by: kvn, coleenp, jmasa
author ysr
date Thu, 03 Dec 2009 15:01:57 -0800
parents a61af66fc99e
children c18cbe5936b8
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1 /*
a61af66fc99e Initial load
duke
parents:
diff changeset
2 * Copyright 1997-2006 Sun Microsystems, Inc. All Rights Reserved.
a61af66fc99e Initial load
duke
parents:
diff changeset
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
a61af66fc99e Initial load
duke
parents:
diff changeset
4 *
a61af66fc99e Initial load
duke
parents:
diff changeset
5 * This code is free software; you can redistribute it and/or modify it
a61af66fc99e Initial load
duke
parents:
diff changeset
6 * under the terms of the GNU General Public License version 2 only, as
a61af66fc99e Initial load
duke
parents:
diff changeset
7 * published by the Free Software Foundation.
a61af66fc99e Initial load
duke
parents:
diff changeset
8 *
a61af66fc99e Initial load
duke
parents:
diff changeset
9 * This code is distributed in the hope that it will be useful, but WITHOUT
a61af66fc99e Initial load
duke
parents:
diff changeset
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
a61af66fc99e Initial load
duke
parents:
diff changeset
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
a61af66fc99e Initial load
duke
parents:
diff changeset
12 * version 2 for more details (a copy is included in the LICENSE file that
a61af66fc99e Initial load
duke
parents:
diff changeset
13 * accompanied this code).
a61af66fc99e Initial load
duke
parents:
diff changeset
14 *
a61af66fc99e Initial load
duke
parents:
diff changeset
15 * You should have received a copy of the GNU General Public License version
a61af66fc99e Initial load
duke
parents:
diff changeset
16 * 2 along with this work; if not, write to the Free Software Foundation,
a61af66fc99e Initial load
duke
parents:
diff changeset
17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
a61af66fc99e Initial load
duke
parents:
diff changeset
18 *
a61af66fc99e Initial load
duke
parents:
diff changeset
19 * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
a61af66fc99e Initial load
duke
parents:
diff changeset
20 * CA 95054 USA or visit www.sun.com if you need additional information or
a61af66fc99e Initial load
duke
parents:
diff changeset
21 * have any questions.
a61af66fc99e Initial load
duke
parents:
diff changeset
22 *
a61af66fc99e Initial load
duke
parents:
diff changeset
23 */
a61af66fc99e Initial load
duke
parents:
diff changeset
24
a61af66fc99e Initial load
duke
parents:
diff changeset
25 #include "incls/_precompiled.incl"
a61af66fc99e Initial load
duke
parents:
diff changeset
26 #include "incls/_events.cpp.incl"
a61af66fc99e Initial load
duke
parents:
diff changeset
27
a61af66fc99e Initial load
duke
parents:
diff changeset
28
a61af66fc99e Initial load
duke
parents:
diff changeset
29 #ifndef PRODUCT
a61af66fc99e Initial load
duke
parents:
diff changeset
30
a61af66fc99e Initial load
duke
parents:
diff changeset
31 ////////////////////////////////////////////////////////////////////////////
a61af66fc99e Initial load
duke
parents:
diff changeset
32 // Event
a61af66fc99e Initial load
duke
parents:
diff changeset
33
a61af66fc99e Initial load
duke
parents:
diff changeset
34 typedef u4 EventID;
a61af66fc99e Initial load
duke
parents:
diff changeset
35
a61af66fc99e Initial load
duke
parents:
diff changeset
36 class Event VALUE_OBJ_CLASS_SPEC {
a61af66fc99e Initial load
duke
parents:
diff changeset
37 private:
a61af66fc99e Initial load
duke
parents:
diff changeset
38 jlong _time_tick;
a61af66fc99e Initial load
duke
parents:
diff changeset
39 intx _thread_id;
a61af66fc99e Initial load
duke
parents:
diff changeset
40 const char* _format;
a61af66fc99e Initial load
duke
parents:
diff changeset
41 int _indent;
a61af66fc99e Initial load
duke
parents:
diff changeset
42 intptr_t _arg_1;
a61af66fc99e Initial load
duke
parents:
diff changeset
43 intptr_t _arg_2;
a61af66fc99e Initial load
duke
parents:
diff changeset
44 intptr_t _arg_3;
a61af66fc99e Initial load
duke
parents:
diff changeset
45
a61af66fc99e Initial load
duke
parents:
diff changeset
46 // only EventBuffer::add_event() can assign event id
a61af66fc99e Initial load
duke
parents:
diff changeset
47 friend class EventBuffer;
a61af66fc99e Initial load
duke
parents:
diff changeset
48 EventID _id;
a61af66fc99e Initial load
duke
parents:
diff changeset
49
a61af66fc99e Initial load
duke
parents:
diff changeset
50 public:
a61af66fc99e Initial load
duke
parents:
diff changeset
51
a61af66fc99e Initial load
duke
parents:
diff changeset
52 void clear() { _format = NULL; }
a61af66fc99e Initial load
duke
parents:
diff changeset
53
a61af66fc99e Initial load
duke
parents:
diff changeset
54 EventID id() const { return _id; }
a61af66fc99e Initial load
duke
parents:
diff changeset
55
a61af66fc99e Initial load
duke
parents:
diff changeset
56 void fill(int indent, const char* format, intptr_t arg_1, intptr_t arg_2, intptr_t arg_3) {
a61af66fc99e Initial load
duke
parents:
diff changeset
57 _format = format;
a61af66fc99e Initial load
duke
parents:
diff changeset
58 _arg_1 = arg_1;
a61af66fc99e Initial load
duke
parents:
diff changeset
59 _arg_2 = arg_2;
a61af66fc99e Initial load
duke
parents:
diff changeset
60 _arg_3 = arg_3;
a61af66fc99e Initial load
duke
parents:
diff changeset
61
a61af66fc99e Initial load
duke
parents:
diff changeset
62 _indent = indent;
a61af66fc99e Initial load
duke
parents:
diff changeset
63
a61af66fc99e Initial load
duke
parents:
diff changeset
64 _thread_id = os::current_thread_id();
a61af66fc99e Initial load
duke
parents:
diff changeset
65 _time_tick = os::elapsed_counter();
a61af66fc99e Initial load
duke
parents:
diff changeset
66 }
a61af66fc99e Initial load
duke
parents:
diff changeset
67
a61af66fc99e Initial load
duke
parents:
diff changeset
68 void print_on(outputStream *st) {
a61af66fc99e Initial load
duke
parents:
diff changeset
69 if (_format == NULL) return;
a61af66fc99e Initial load
duke
parents:
diff changeset
70 st->print(" %d", _thread_id);
a61af66fc99e Initial load
duke
parents:
diff changeset
71 st->print(" %3.2g ", (double)_time_tick / os::elapsed_frequency());
a61af66fc99e Initial load
duke
parents:
diff changeset
72 st->fill_to(20);
a61af66fc99e Initial load
duke
parents:
diff changeset
73 for (int index = 0; index < _indent; index++) {
a61af66fc99e Initial load
duke
parents:
diff changeset
74 st->print("| ");
a61af66fc99e Initial load
duke
parents:
diff changeset
75 }
a61af66fc99e Initial load
duke
parents:
diff changeset
76 st->print_cr(_format, _arg_1, _arg_2, _arg_3);
a61af66fc99e Initial load
duke
parents:
diff changeset
77 }
a61af66fc99e Initial load
duke
parents:
diff changeset
78 };
a61af66fc99e Initial load
duke
parents:
diff changeset
79
a61af66fc99e Initial load
duke
parents:
diff changeset
80 ////////////////////////////////////////////////////////////////////////////
a61af66fc99e Initial load
duke
parents:
diff changeset
81 // EventBuffer
a61af66fc99e Initial load
duke
parents:
diff changeset
82 //
a61af66fc99e Initial load
duke
parents:
diff changeset
83 // Simple lock-free event queue. Every event has a unique 32-bit id.
a61af66fc99e Initial load
duke
parents:
diff changeset
84 // It's fine if two threads add events at the same time, because they
a61af66fc99e Initial load
duke
parents:
diff changeset
85 // will get different event id, and then write to different buffer location.
a61af66fc99e Initial load
duke
parents:
diff changeset
86 // However, it is assumed that add_event() is quick enough (or buffer size
a61af66fc99e Initial load
duke
parents:
diff changeset
87 // is big enough), so when one thread is adding event, there can't be more
a61af66fc99e Initial load
duke
parents:
diff changeset
88 // than "size" events created by other threads; otherwise we'll end up having
a61af66fc99e Initial load
duke
parents:
diff changeset
89 // two threads writing to the same location.
a61af66fc99e Initial load
duke
parents:
diff changeset
90
a61af66fc99e Initial load
duke
parents:
diff changeset
91 class EventBuffer : AllStatic {
a61af66fc99e Initial load
duke
parents:
diff changeset
92 private:
a61af66fc99e Initial load
duke
parents:
diff changeset
93 static Event* buffer;
a61af66fc99e Initial load
duke
parents:
diff changeset
94 static int size;
a61af66fc99e Initial load
duke
parents:
diff changeset
95 static jint indent;
a61af66fc99e Initial load
duke
parents:
diff changeset
96 static volatile EventID _current_event_id;
a61af66fc99e Initial load
duke
parents:
diff changeset
97
a61af66fc99e Initial load
duke
parents:
diff changeset
98 static EventID get_next_event_id() {
a61af66fc99e Initial load
duke
parents:
diff changeset
99 return (EventID)Atomic::add(1, (jint*)&_current_event_id);
a61af66fc99e Initial load
duke
parents:
diff changeset
100 }
a61af66fc99e Initial load
duke
parents:
diff changeset
101
a61af66fc99e Initial load
duke
parents:
diff changeset
102 public:
a61af66fc99e Initial load
duke
parents:
diff changeset
103 static void inc_indent() { Atomic::inc(&indent); }
a61af66fc99e Initial load
duke
parents:
diff changeset
104 static void dec_indent() { Atomic::dec(&indent); }
a61af66fc99e Initial load
duke
parents:
diff changeset
105
a61af66fc99e Initial load
duke
parents:
diff changeset
106 static bool get_event(EventID id, Event* event) {
a61af66fc99e Initial load
duke
parents:
diff changeset
107 int index = (int)(id % size);
a61af66fc99e Initial load
duke
parents:
diff changeset
108 if (buffer[index].id() == id) {
a61af66fc99e Initial load
duke
parents:
diff changeset
109 memcpy(event, &buffer[index], sizeof(Event));
a61af66fc99e Initial load
duke
parents:
diff changeset
110 // check id again; if buffer[index] is being updated by another thread,
a61af66fc99e Initial load
duke
parents:
diff changeset
111 // event->id() will contain different value.
a61af66fc99e Initial load
duke
parents:
diff changeset
112 return (event->id() == id);
a61af66fc99e Initial load
duke
parents:
diff changeset
113 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
114 // id does not match - id is invalid, or event is overwritten
a61af66fc99e Initial load
duke
parents:
diff changeset
115 return false;
a61af66fc99e Initial load
duke
parents:
diff changeset
116 }
a61af66fc99e Initial load
duke
parents:
diff changeset
117 }
a61af66fc99e Initial load
duke
parents:
diff changeset
118
a61af66fc99e Initial load
duke
parents:
diff changeset
119 // add a new event to the queue; if EventBuffer is full, this call will
a61af66fc99e Initial load
duke
parents:
diff changeset
120 // overwrite the oldest event in the queue
a61af66fc99e Initial load
duke
parents:
diff changeset
121 static EventID add_event(const char* format,
a61af66fc99e Initial load
duke
parents:
diff changeset
122 intptr_t arg_1, intptr_t arg_2, intptr_t arg_3) {
a61af66fc99e Initial load
duke
parents:
diff changeset
123 // assign a unique id
a61af66fc99e Initial load
duke
parents:
diff changeset
124 EventID id = get_next_event_id();
a61af66fc99e Initial load
duke
parents:
diff changeset
125
a61af66fc99e Initial load
duke
parents:
diff changeset
126 // event will be copied to buffer[index]
a61af66fc99e Initial load
duke
parents:
diff changeset
127 int index = (int)(id % size);
a61af66fc99e Initial load
duke
parents:
diff changeset
128
a61af66fc99e Initial load
duke
parents:
diff changeset
129 // first, invalidate id, buffer[index] can't have event with id = index + 2
a61af66fc99e Initial load
duke
parents:
diff changeset
130 buffer[index]._id = index + 2;
a61af66fc99e Initial load
duke
parents:
diff changeset
131
a61af66fc99e Initial load
duke
parents:
diff changeset
132 // make sure everyone has seen that buffer[index] is invalid
a61af66fc99e Initial load
duke
parents:
diff changeset
133 OrderAccess::fence();
a61af66fc99e Initial load
duke
parents:
diff changeset
134
a61af66fc99e Initial load
duke
parents:
diff changeset
135 // ... before updating its value
a61af66fc99e Initial load
duke
parents:
diff changeset
136 buffer[index].fill(indent, format, arg_1, arg_2, arg_3);
a61af66fc99e Initial load
duke
parents:
diff changeset
137
a61af66fc99e Initial load
duke
parents:
diff changeset
138 // finally, set up real event id, now buffer[index] contains valid event
a61af66fc99e Initial load
duke
parents:
diff changeset
139 OrderAccess::release_store(&(buffer[index]._id), id);
a61af66fc99e Initial load
duke
parents:
diff changeset
140
a61af66fc99e Initial load
duke
parents:
diff changeset
141 return id;
a61af66fc99e Initial load
duke
parents:
diff changeset
142 }
a61af66fc99e Initial load
duke
parents:
diff changeset
143
a61af66fc99e Initial load
duke
parents:
diff changeset
144 static void print_last(outputStream *st, int number) {
a61af66fc99e Initial load
duke
parents:
diff changeset
145 st->print_cr("[Last %d events in the event buffer]", number);
a61af66fc99e Initial load
duke
parents:
diff changeset
146 st->print_cr("-<thd>-<elapsed sec>-<description>---------------------");
a61af66fc99e Initial load
duke
parents:
diff changeset
147
a61af66fc99e Initial load
duke
parents:
diff changeset
148 int count = 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
149 EventID id = _current_event_id;
a61af66fc99e Initial load
duke
parents:
diff changeset
150 while (count < number) {
a61af66fc99e Initial load
duke
parents:
diff changeset
151 Event event;
a61af66fc99e Initial load
duke
parents:
diff changeset
152 if (get_event(id, &event)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
153 event.print_on(st);
a61af66fc99e Initial load
duke
parents:
diff changeset
154 }
a61af66fc99e Initial load
duke
parents:
diff changeset
155 id--;
a61af66fc99e Initial load
duke
parents:
diff changeset
156 count++;
a61af66fc99e Initial load
duke
parents:
diff changeset
157 }
a61af66fc99e Initial load
duke
parents:
diff changeset
158 }
a61af66fc99e Initial load
duke
parents:
diff changeset
159
a61af66fc99e Initial load
duke
parents:
diff changeset
160 static void print_all(outputStream* st) {
a61af66fc99e Initial load
duke
parents:
diff changeset
161 print_last(st, size);
a61af66fc99e Initial load
duke
parents:
diff changeset
162 }
a61af66fc99e Initial load
duke
parents:
diff changeset
163
a61af66fc99e Initial load
duke
parents:
diff changeset
164 static void init() {
a61af66fc99e Initial load
duke
parents:
diff changeset
165 // Allocate the event buffer
a61af66fc99e Initial load
duke
parents:
diff changeset
166 size = EventLogLength;
a61af66fc99e Initial load
duke
parents:
diff changeset
167 buffer = NEW_C_HEAP_ARRAY(Event, size);
a61af66fc99e Initial load
duke
parents:
diff changeset
168
a61af66fc99e Initial load
duke
parents:
diff changeset
169 _current_event_id = 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
170
a61af66fc99e Initial load
duke
parents:
diff changeset
171 // Clear the event buffer
a61af66fc99e Initial load
duke
parents:
diff changeset
172 for (int index = 0; index < size; index++) {
a61af66fc99e Initial load
duke
parents:
diff changeset
173 buffer[index]._id = index + 1; // index + 1 is invalid id
a61af66fc99e Initial load
duke
parents:
diff changeset
174 buffer[index].clear();
a61af66fc99e Initial load
duke
parents:
diff changeset
175 }
a61af66fc99e Initial load
duke
parents:
diff changeset
176 }
a61af66fc99e Initial load
duke
parents:
diff changeset
177 };
a61af66fc99e Initial load
duke
parents:
diff changeset
178
a61af66fc99e Initial load
duke
parents:
diff changeset
179 Event* EventBuffer::buffer;
a61af66fc99e Initial load
duke
parents:
diff changeset
180 int EventBuffer::size;
a61af66fc99e Initial load
duke
parents:
diff changeset
181 volatile EventID EventBuffer::_current_event_id;
a61af66fc99e Initial load
duke
parents:
diff changeset
182 int EventBuffer::indent;
a61af66fc99e Initial load
duke
parents:
diff changeset
183
a61af66fc99e Initial load
duke
parents:
diff changeset
184 ////////////////////////////////////////////////////////////////////////////
a61af66fc99e Initial load
duke
parents:
diff changeset
185 // Events
a61af66fc99e Initial load
duke
parents:
diff changeset
186
a61af66fc99e Initial load
duke
parents:
diff changeset
187 // Events::log() is safe for signal handlers
a61af66fc99e Initial load
duke
parents:
diff changeset
188 void Events::log(const char* format, ...) {
a61af66fc99e Initial load
duke
parents:
diff changeset
189 if (LogEvents) {
a61af66fc99e Initial load
duke
parents:
diff changeset
190 va_list ap;
a61af66fc99e Initial load
duke
parents:
diff changeset
191 va_start(ap, format);
a61af66fc99e Initial load
duke
parents:
diff changeset
192 intptr_t arg_1 = va_arg(ap, intptr_t);
a61af66fc99e Initial load
duke
parents:
diff changeset
193 intptr_t arg_2 = va_arg(ap, intptr_t);
a61af66fc99e Initial load
duke
parents:
diff changeset
194 intptr_t arg_3 = va_arg(ap, intptr_t);
a61af66fc99e Initial load
duke
parents:
diff changeset
195 va_end(ap);
a61af66fc99e Initial load
duke
parents:
diff changeset
196
a61af66fc99e Initial load
duke
parents:
diff changeset
197 EventBuffer::add_event(format, arg_1, arg_2, arg_3);
a61af66fc99e Initial load
duke
parents:
diff changeset
198 }
a61af66fc99e Initial load
duke
parents:
diff changeset
199 }
a61af66fc99e Initial load
duke
parents:
diff changeset
200
a61af66fc99e Initial load
duke
parents:
diff changeset
201 void Events::print_all(outputStream *st) {
a61af66fc99e Initial load
duke
parents:
diff changeset
202 EventBuffer::print_all(st);
a61af66fc99e Initial load
duke
parents:
diff changeset
203 }
a61af66fc99e Initial load
duke
parents:
diff changeset
204
a61af66fc99e Initial load
duke
parents:
diff changeset
205 void Events::print_last(outputStream *st, int number) {
a61af66fc99e Initial load
duke
parents:
diff changeset
206 EventBuffer::print_last(st, number);
a61af66fc99e Initial load
duke
parents:
diff changeset
207 }
a61af66fc99e Initial load
duke
parents:
diff changeset
208
a61af66fc99e Initial load
duke
parents:
diff changeset
209 ///////////////////////////////////////////////////////////////////////////
a61af66fc99e Initial load
duke
parents:
diff changeset
210 // EventMark
a61af66fc99e Initial load
duke
parents:
diff changeset
211
a61af66fc99e Initial load
duke
parents:
diff changeset
212 EventMark::EventMark(const char* format, ...) {
a61af66fc99e Initial load
duke
parents:
diff changeset
213 if (LogEvents) {
a61af66fc99e Initial load
duke
parents:
diff changeset
214 va_list ap;
a61af66fc99e Initial load
duke
parents:
diff changeset
215 va_start(ap, format);
a61af66fc99e Initial load
duke
parents:
diff changeset
216 intptr_t arg_1 = va_arg(ap, intptr_t);
a61af66fc99e Initial load
duke
parents:
diff changeset
217 intptr_t arg_2 = va_arg(ap, intptr_t);
a61af66fc99e Initial load
duke
parents:
diff changeset
218 intptr_t arg_3 = va_arg(ap, intptr_t);
a61af66fc99e Initial load
duke
parents:
diff changeset
219 va_end(ap);
a61af66fc99e Initial load
duke
parents:
diff changeset
220
a61af66fc99e Initial load
duke
parents:
diff changeset
221 EventBuffer::add_event(format, arg_1, arg_2, arg_3);
a61af66fc99e Initial load
duke
parents:
diff changeset
222 EventBuffer::inc_indent();
a61af66fc99e Initial load
duke
parents:
diff changeset
223 }
a61af66fc99e Initial load
duke
parents:
diff changeset
224 }
a61af66fc99e Initial load
duke
parents:
diff changeset
225
a61af66fc99e Initial load
duke
parents:
diff changeset
226 EventMark::~EventMark() {
a61af66fc99e Initial load
duke
parents:
diff changeset
227 if (LogEvents) {
a61af66fc99e Initial load
duke
parents:
diff changeset
228 EventBuffer::dec_indent();
a61af66fc99e Initial load
duke
parents:
diff changeset
229 EventBuffer::add_event("done", 0, 0, 0);
a61af66fc99e Initial load
duke
parents:
diff changeset
230 }
a61af66fc99e Initial load
duke
parents:
diff changeset
231 }
a61af66fc99e Initial load
duke
parents:
diff changeset
232
a61af66fc99e Initial load
duke
parents:
diff changeset
233 ///////////////////////////////////////////////////////////////////////////
a61af66fc99e Initial load
duke
parents:
diff changeset
234
a61af66fc99e Initial load
duke
parents:
diff changeset
235 void eventlog_init() {
a61af66fc99e Initial load
duke
parents:
diff changeset
236 EventBuffer::init();
a61af66fc99e Initial load
duke
parents:
diff changeset
237 }
a61af66fc99e Initial load
duke
parents:
diff changeset
238
a61af66fc99e Initial load
duke
parents:
diff changeset
239 int print_all_events(outputStream *st) {
a61af66fc99e Initial load
duke
parents:
diff changeset
240 EventBuffer::print_all(st);
a61af66fc99e Initial load
duke
parents:
diff changeset
241 return 1;
a61af66fc99e Initial load
duke
parents:
diff changeset
242 }
a61af66fc99e Initial load
duke
parents:
diff changeset
243
a61af66fc99e Initial load
duke
parents:
diff changeset
244 #else
a61af66fc99e Initial load
duke
parents:
diff changeset
245
a61af66fc99e Initial load
duke
parents:
diff changeset
246 void eventlog_init() {}
a61af66fc99e Initial load
duke
parents:
diff changeset
247 int print_all_events(outputStream *st) { return 0; }
a61af66fc99e Initial load
duke
parents:
diff changeset
248
a61af66fc99e Initial load
duke
parents:
diff changeset
249 #endif // PRODUCT