-
-
Notifications
You must be signed in to change notification settings - Fork 925
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #3938 from headius/flag_registry
Flag registry
- 9.4.12.0
- 9.4.11.0
- 9.4.10.0
- 9.4.9.0
- 9.4.8.0
- 9.4.7.0
- 9.4.6.0
- 9.4.5.0
- 9.4.4.0
- 9.4.3.0
- 9.4.2.0
- 9.4.1.0
- 9.4.0.0
- 9.3.15.0
- 9.3.14.0
- 9.3.13.0
- 9.3.12.0
- 9.3.11.0
- 9.3.10.0
- 9.3.9.0
- 9.3.8.0
- 9.3.7.0
- 9.3.6.0
- 9.3.5.0
- 9.3.4.0
- 9.3.3.0
- 9.3.2.0
- 9.3.1.0
- 9.3.0.0
- 9.2.21.0
- 9.2.20.1
- 9.2.20.0
- 9.2.19.0
- 9.2.18.0
- 9.2.17.0
- 9.2.16.0
- 9.2.15.0
- 9.2.14.0
- 9.2.13.0
- 9.2.12.0
- 9.2.11.1
- 9.2.11.0
- 9.2.10.0
- 9.2.9.0
- 9.2.8.0
- 9.2.7.0
- 9.2.6.0
- 9.2.5.0
- 9.2.4.1
- 9.2.4.0
- 9.2.3.0
- 9.2.2.0
- 9.2.1.0
- 9.2.0.0
- 9.1.17.0
- 9.1.16.0
- 9.1.15.0
- 9.1.14.0
- 9.1.13.0
- 9.1.12.0
- 9.1.11.0
- 9.1.10.0
- 9.1.9.0
- 9.1.8.0
- 9.1.7.0
- 9.1.6.0
- 9.1.5.0
- 9.1.4.0
- 9.1.3.0
Showing
9 changed files
with
186 additions
and
57 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,75 @@ | ||
package org.jruby; | ||
|
||
import java.util.BitSet; | ||
import java.util.HashMap; | ||
import java.util.Map; | ||
|
||
/** | ||
* This class serves as a registry of all bit flags we use on JRuby objects. | ||
* | ||
* In order to maximally use our bit flags and prevent overlap between ancestors and dependents, | ||
* this class registers flags on a first-come, first-served basis using previous flags registered | ||
* for ancestor classes as a base line for new flags in a descendant. | ||
* | ||
* Because of the first-come, first-served nature, the most general types will need to register | ||
* their flags first. This guarantees all bit flags from the progenitor on down will be packed | ||
* tightly while avoiding overlaps. | ||
*/ | ||
public class FlagRegistry { | ||
private final Map<Class, Integer> currentShift = new HashMap<>(); | ||
private final Map<Class, BitSet> registry = new HashMap<>(); | ||
|
||
/** | ||
* Register a new flag for the given class. | ||
* | ||
* The bit index for the new flag will be calculated at runtime, by walking parent classes | ||
* and looking for previously-registered flags. Ancestors should register all their flags | ||
* before decendants (which means they should not be registered in a static initializer | ||
* unless the parent is known to have fully run its own static initializers). | ||
* | ||
* @param klass the class for which to register a new flag | ||
* @return an integer with the new flag bit set | ||
*/ | ||
public synchronized int newFlag(Class klass) { | ||
Class currentKlass = klass; | ||
Integer shift = null; | ||
while (currentKlass != null && | ||
(shift = currentShift.get(currentKlass)) == null) { | ||
currentKlass = currentKlass.getSuperclass(); | ||
} | ||
if (shift == null) shift = 0; | ||
|
||
BitSet flags = registry.get(klass); | ||
if (flags == null) { | ||
flags = new BitSet(); | ||
registry.put(klass, flags); | ||
} | ||
flags.set(shift); | ||
|
||
assert flagsAreValid(klass, shift); | ||
|
||
currentShift.put(klass, shift + 1); | ||
|
||
return 1 << shift++; | ||
} | ||
|
||
public synchronized void printFlags() { | ||
System.out.println(registry); | ||
} | ||
|
||
private boolean flagsAreValid(Class klass, int bitIndex) { | ||
BitSet gathered = new BitSet(); | ||
Class currentKlass = klass; | ||
while (currentKlass != null) { | ||
BitSet flags = registry.get(klass); | ||
if (flags != null) { | ||
if (flags.intersects(gathered)) { | ||
throw new AssertionError(klass.getName() + " uses flag " + bitIndex + " that overlaps with " + currentKlass); | ||
} | ||
gathered.and(flags); | ||
} | ||
currentKlass = currentKlass.getSuperclass(); | ||
} | ||
return true; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters