pjt33
|
 |
«
Reply #270 - Posted
2012-09-13 00:01:48 » |
|
WRT: Unsigned again, no need for new bytecodes. You almost never need new bytecodes. Shifts and masks are trivial transforms and HotSpot is not a simple JIT. Signed/Unsigned conversion has been fast forever. Compares, divides & multiples have harder and more numerous patterns...JDK8 adds methods (with software backup implementations), runtime coverts to a single opcode, done.
Wait: are you saying that there are already bytecodes for signed/unsigned conversion? If so, someone needs to tell Oracle to update the VM spec. Or are you proposing that unsigned types would be added at the VM level without changing the type system, just adding some kind of annotation to indicate which stack slots hold untyped primitives in which instruction ranges, a là LocalVariableTable?
|
|
|
|
|
Riven
|
 |
«
Reply #271 - Posted
2012-09-13 00:33:20 » |
|
As Roquen said: Intrinsics
Make every (arithmetic) operation a method call, and there is no need whatsoever so introduce new bytecodes.
|
|
|
|
Roquen
|
 |
«
Reply #272 - Posted
2012-09-13 11:46:43 » |
|
JVM bytecodes (and likewise for CLR) are very misleading. These designs are very good for being able to quickly create (with little compiler/architecture knowledge) small footprint VMs based on interpretation and/or trivial JITs, including the loading/linking/verification stages. These designs are really bad for being fed to a "real" compiler frameworks such as HotSpot and .NET. So you cannot look at the bytecodes, assuming a real compiler, to determine much about what the final result is going to look like. Bytecodes are simply a transport intermediate representation (IR), or high level language if you will. Nor can you simply examine the "source" of library calls. A fair number of library calls have source code implementations which are only designed to be software fallback for hardware which doesn't support the operation and/or to make porting to new architectures easier to get up and running. (SEE: wiki page on intrinsic list)
Conversions between integers widths within a larger bit-width integer are all trival transforms and don't need any special case handling, say via an intrinsic (to be more precise in terminology than my previous statement). So some M-expression pseudo-code for transform pretty much any half-way sane compiler should be able to always handle: int t = (x<<24)>>24; -> t = LoadSignedByte[FieldOffset[this, "x"]] int t = x & 0xFF -> t = LoadUnsignedByte[FieldOffset[this, "x"]]
On the other hand many transforms that might seem easy cannot be performed as the compiler may not be able to know that it's legal: int t = x/2; // if x cannot be statically known to be >= 0, this cannot be converted into a shift
Floating point operations are a prime example as the rules are strict, so tons of things which might seem possible are in fact not (esp. since Java's design does not allow for any relaxation of rules...well almost)
Intrinsics, in the context of JVM/CLR like systems, are specially marked methods that are auto-magically replaced at load/link/verifier time by some transform assuming that they are supported on the target architecture. The folks working on HotSpot "might" make some of these conversion methods into intrinsic, even though it isn't needed, simply to lower the burden further down the chain. However the real purpose of intrinsics is allow code-sequences which cannot be expressed (at all or in simple to identify patterns) to be converted into high performance versions (frequently a single native opcode). sin, cos, sqrt, etc. etc. In this context unsigned compares, multiples and divides have many possible formulations of complex chains of operations, so they will be supported as intrinsic methods which will all end up as a single opcode, just like their signed equivalent.
Yeah, I think it would be nice to have operators for these unsigned ops, but then I'm a weirdo that considers operator overload to be full-of-awesomeness (just to beat a dead horse even more).
|
|
|
|
|
Games published by our own members! Check 'em out!
|
|
Oskuro
|
 |
«
Reply #273 - Posted
2012-09-13 13:37:45 » |
|
I'm a weirdo that considers operator overload to be full-of-awesomeness You're not the only one.  Also, great post. Very informative.
|
|
|
|
pjt33
|
 |
«
Reply #274 - Posted
2012-09-13 20:25:33 » |
|
I still haven't quite pinned you down, Roquen.
Is your proposal for implementing unsigned types without extra bytecodes to not introduce any new types at the VM level, and have the compiler box normal signed types in new unsigned wrappers? It would still need some kind of annotation so that it's known at method resolution time whether the types in the signature are the virtual unsigned primitives or the wrapper classes, so there would still be some changes required to the VM spec.
Or do you add types at runtime for signature purposes only and have conversion between signed and unsigned go via an unsafe method?
|
|
|
|
|
Roquen
|
 |
«
Reply #275 - Posted
2012-09-13 21:22:12 » |
|
The root of the "problem" here is the notion that signed and unsigned integers are different. They are not (since 2s comp form). Computer integers are neither signed nor unsigned...that's just an interpretation of the bit-pattern that you're choosing to make at any given time. As such it has different sets of operators based on which representation you're currently thinking in. As an example, java has always had "unsigned" right shifts...it's just a different operator than "signed" right shifts. Same for compares, multiples and divides. So called conversion is just bit twiddling when expanding the width.
|
|
|
|
|
pjt33
|
 |
«
Reply #276 - Posted
2012-09-13 21:54:51 » |
|
The root of the "problem" here is the notion that signed and unsigned integers are different. No it isn't. The difference between datatypes is indeed the interpretation of the bits, but it's precisely the fact that bits can be interpreted in more than one way which makes the type system necessary. Now, it's true that unsigned arithmetic can be performed without adding any primitive types to the language, but I'm taking it as read that "adding unsigned types to Java" means adding unsigned primitive types to the JLS - otherwise people would just write a library rather than a JCR. And that needs to be done in a way which is consistent with expectations for primitive types: in particular, they can't be null, and they're distinct for the purposes of method overloading and resolution. As such they need some VM support: if they're implemented by compilation down to object types, they will be nullable and e.g. can't be treated as primitives in the context of reflection; and if they're implemented by compilation down to existing primitive types, method overloading becomes impossible.
|
|
|
|
|
Roquen
|
 |
«
Reply #277 - Posted
2012-09-13 22:41:34 » |
|
Well then, from my perspective I'm getting unsigned integer support in JDK8 and they're doing in such a way that requires the least work by just adding methods for the missing operators. Adding them as new types to the specification would be a massive undertaking which would result in pretty much nothing (other than a new set of possible signatures) which IHMO would cause more problems than it would solve. The whole point of not supporting unsigned as types in the first place was to prevent ambiguous statements.
People have written libraries, but 3rd party library calls are not converted into intrinsic methods. I'm not sure where you're coming from with objects and null here. None of this is VM (from a specification standpoint) aware. It all happens under the hood of the compiler which simply insures none of the JVM rules are violated by its transforms.
|
|
|
|
|
sproingie
|
 |
«
Reply #278 - Posted
2012-09-13 22:57:53 » |
|
I'm certain JDK8 is only getting unsigned integer support as library operations that just happen to become intrinsics. No larger literals, no 'unsigned' keyword for us now or likely in the forseeable future, for much the same reasons given, that adding a new primitive makes signatures a bear. From the way Gosling mentioned it though, it really wasn't a principled decision to leave out unsigned so much as something they just never got around to.
|
|
|
|
|
pjt33
|
 |
«
Reply #279 - Posted
2012-09-14 22:31:03 » |
|
I'm not sure where you're coming from with objects and null here.
I was taking my context from replies #242, #243, and #245, which are about adding new primitive types at the language level, whereas you were talking about an implementation of "unsigned types" which doesn't actually add any types, even at the language level. No wonder we've been talking past each other for 3 days. (I'm still not sure what Riven was proposing in #245, but never mind).
|
|
|
|
|
Games published by our own members! Check 'em out!
|
|
Best Username Ever
|
 |
«
Reply #280 - Posted
2012-09-15 05:56:59 » |
|
Things that are bothering me today: - "For each" loops expect an Iterable instead of an Iterator or Iterable object.
- There is no way to group primitives similar to a C struct type.
- Iterators can't return structs because structs don't exist.
- Iterators can't return structs or primatives because Generics only works for Objects.
- There is no way for Iterators to return multiple values (as in x-y coordinates, key/value pairs, etc) without creating wrapper classes.
- There are actual bugs (fruit flies?) crawling on my screen while I code, but only when my IDE is the front window...

|
|
|
|
|
Jack Ammo
Junior Newbie
|
 |
«
Reply #281 - Posted
2012-09-15 06:19:37 » |
|
I guess I'm kinda new to programming to be asking this but wouldn't a class which has no methods and only data fields be the same functionality-wise as a struct? or am I missing something that java does with classes that just isn't what you want from a struct 
|
fading away until all that's left is but a distant memory
|
|
|
Jimmt
|
 |
«
Reply #282 - Posted
2012-09-15 06:29:55 » |
|
We don't have structs. I suppose enums are somewhat similar, but no methods and stuff in enums...
|
|
|
|
|
sproingie
|
 |
«
Reply #283 - Posted
2012-09-15 06:31:51 » |
|
"Struct" in java-land tends to mean a stack-allocated value type. I don't see what they have to do with iterators at all. Lack of tuple types is annoying, again not really related to iteration...
It's a touch annoying there's no syntax for iterating over an existing Iterator, but I can see the reasoning. Even more annoying is that you can't get at the Iterator instance in foreach syntax so it's useless if you want to use remove()
|
|
|
|
|
Roquen
|
 |
«
Reply #284 - Posted
2012-09-15 09:06:26 » |
|
I'd say that structs are (hopefully) about designing data-structures in linear memory. There's been some talk about adding some tuple like structures.
|
|
|
|
|
|
|
Best Username Ever
|
 |
«
Reply #286 - Posted
2012-09-15 17:30:59 » |
|
Java classes != C++ classes. Adding "structs" without changing classes would add a lot to Java, but currently you cannot use classes like (value type) structs/tuples. 1 2 3 4 5 6 7 8
| Point p = new Point(123, 456); Map<Point, String> map = new HashMap<Point, String>(); map.put(p, "A"); Point p2 = p.copy(); p.x *= -1; p.y *= -1; System.out.println(map.get(p)); System.out.println(map.get(p2)); |
| Java | C++ | | Primitives | Val | Val | | Structs | NA | Val | | Classes | Ref | Val | | Arrays | Ref | Val/ Ptr |
|
|
|
|
|
Roquen
|
 |
«
Reply #287 - Posted
2012-09-15 19:56:32 » |
|
Even in-house engineers working on Java acknowledge that adding structs is one of the things needed to close the performance gap between dynamically vs. statically compiled languages.
|
|
|
|
|
ra4king
|
 |
«
Reply #288 - Posted
2012-09-15 21:08:44 » |
|
Java classes != C++ classes. Adding "structs" without changing classes would add a lot to Java, but currently you cannot use classes like (value type) structs/tuples. 1 2 3 4 5 6 7 8
| Point p = new Point(123, 456); Map<Point, String> map = new HashMap<Point, String>(); map.put(p, "A"); Point p2 = p.copy(); p.x *= -1; p.y *= -1; System.out.println(map.get(p)); System.out.println(map.get(p2)); |
First one should print "A" and the second one should be null.....unless I'm blind 
|
|
|
|
pjt33
|
 |
«
Reply #289 - Posted
2012-09-16 00:02:54 » |
|
First one should print "A" and the second one should be null.....unless I'm blind  Inserting an object into a hashmap and then changing its hashcode is fairly likely (although not certain) to make get fail.
|
|
|
|
|
ra4king
|
 |
«
Reply #290 - Posted
2012-09-16 00:41:38 » |
|
The 'p' instance inside the HashMap is the same instance as the 'p' you're passing in, no matter how different the variables inside 'p' are  'p2' fails because it's a different instance.
|
|
|
|
pjt33
|
 |
«
Reply #291 - Posted
2012-09-16 00:52:40 » |
|
The 'p' instance inside the HashMap is the same instance as the 'p' you're passing in, no matter how different the variables inside 'p' are  This is true but irrelevant. Actually in this case (substituting , which exists, for , which doesn't) it happens to output A, but that's because 1
| java.awt.geom.Point2D.hashCode() |
is implemented (roughly speaking) as an xor of the two parameters; remove the line and test it and you'll see that it fails.
|
|
|
|
|
Best Username Ever
|
 |
«
Reply #292 - Posted
2012-09-16 01:05:59 » |
|
I was working with a hypothetical class to illustrate one of the problems with using reference types exclusively. I assumed it overrode hashcode and equals, but even if it didn't, then you would still have other problems with assuming objects were the same as structs. (Although if I were designing a class I would not override equals or hashcode for a mutable Object.) Emulating by value assignment for groups of values using reference types means you either have to make the object immutable (which will require excessive copying, memory management overhead, extra code, and extra memory usage) or that you have to defensive copies of any value you rely on (which has all the same problems.)
I don't know if Java counts as being dynamically compiled. The distinction doesn't even exist now. We now have C and C++ interpreters, Janino, GCJ, etc. What matters most is static typing. Java could use structs to a much greater advantage than dynamically typed languages.
|
|
|
|
|
Jack Ammo
Junior Newbie
|
 |
«
Reply #293 - Posted
2012-09-16 09:01:57 » |
|
thanks everyone for explaining this for me. I appreciate it as I try to get better.
|
fading away until all that's left is but a distant memory
|
|
|
|