MCPcopy Create free account
hub / github.com/google/re2j / put

Method put

java/com/google/re2j/RE2.java:239–284  ·  view source on GitHub ↗
(Machine m, boolean isNew)

Source from the content-addressed store, hash-verified

237 // simultaneous matches run using |this|. (The cache empties when |this|
238 // gets garbage collected or reset is called.)
239 @SuppressWarnings("MakeAlwaysEqual") // for ErrorProne, see below
240 void put(Machine m, boolean isNew) {
241 // To avoid allocation in the single-thread or uncontended case, reuse a node only if
242 // it was the only element in the stack when it was popped, and it's the only element
243 // in the stack when it's pushed back after use.
244 Machine head;
245 do {
246 head = pooled.get();
247 if (!isNew && head != null) {
248 // If an element had a null next pointer and it was previously in the stack, another thread
249 // might be trying to pop it out right now, and if it sees the same node now in the
250 // stack the pop will succeed, but the new top of the stack will be the stale (null) value
251 // of next. Allocate a new Machine so that the CAS will not succeed if this node has been
252 // popped and re-pushed.
253 m = new Machine(m);
254 isNew = true;
255 }
256
257 // Without this comparison, TSAN will complain about a race condition:
258 // Thread A, B, and C all attempt to do a match on the same pattern.
259 //
260 // A: Allocates Machine 1; executes match; put machine 1. State is now:
261 //
262 // pooled -> machine 1 -> null
263 //
264 // B reads pooled, sees machine 1
265 //
266 // C reads pooled, sees machine 1
267 //
268 // B successfully CASes pooled to null
269 //
270 // B executes match; put machine 1, which involves setting machine1.next to
271 // null (even though it's already null); preempted before CAS
272 //
273 // C resumes, and reads machine1.next in order to execute cas(head, head.next)
274 //
275 // There is no happens-before relationship between B's redundant null write
276 // and C's read, thus triggering TSAN.
277 //
278 // A future release of ErrorProne may want to make the assignment unconditionally. The
279 // @SuppressWarning("MakeAlwaysEqual") on this method is intended to prevent that from happening.
280 if (m.next != head) {
281 m.next = head;
282 }
283 } while (!pooled.compareAndSet(head, m));
284 }
285
286 @Override
287 public String toString() {

Callers 10

doExecuteMethod · 0.95
ParserTestClass · 0.80
CharGroupClass · 0.80
CategoriesMethod · 0.80
ScriptsMethod · 0.80
FoldScriptMethod · 0.80
FoldCategoryMethod · 0.80
parsePerlFlagsMethod · 0.80

Calls 1

getMethod · 0.80

Tested by

no test coverage detected