> It is madness – and no amount of mansplaining from billionaires will be adequate to justify it.
We can certainly discuss about the data and how to interpret it, but using such phrases in a newspaper-article isn't really helpful either.
531 karma · joined September 3, 2016
> It is madness – and no amount of mansplaining from billionaires will be adequate to justify it.
We can certainly discuss about the data and how to interpret it, but using such phrases in a newspaper-article isn't really helpful either.
Not sure I agree with that. Copying references between local variables and reads/writes from heap all require expensive atomic operations for RC when they can't be optimized away. That's a major performance problem for languages like Swift. I do not say that one is better than the other, but this is exactly where tracing GC's shine compared to RC.
In the case of ZGC these doesn't require atomic operations, you need a read barrier for reading references from the heap though. But do not conflate tracing GC's read & write barriers with atomic barriers.
Even if we consider that good enough or somehow solved, understanding type annotations only helps you reaching peak performance faster. It doesn't really make peak performance faster.
Also there are the PyPy and Dart devs that in theory could use type annotations, but both don't. For PyPy they even have an entry in the FAQ: http://doc.pypy.org/en/latest/faq.html#would-type-annotation...
This missing separation is even a problem for writing tests in GCC: Often it would be quite easy to write a small program in GIMPLE-IR (or RTL) and test your optimization pass against it. But you can't write GIMPLE-IR (it needs to go through GENERIC all the time), so you need to write a C file that is then translated into the IR you want to test again. This is sometimes not so easy with all that different optimization passes that run before your pass and hopefully that doesn't change in the future either.... There was some work on this (I don't know about the current status) but almost all of GCC's tests are still integration tests against C files (I think they addressed this by extending the C-front end to be able to parse functions marked with __gimple as Gimple-IR). Also GIMPLE didn't start as a separate IR. It started as a more restricted tree-structure. Even today operands are still tree's and optimization passes are called tree-<something>.c.
With LLVM I can write a toy compiler that outputs LLVM IR with printf and then just pipe it into llc to compile it. That's pretty cool. I didn't want to imply that GCC has NO separation between IRs but the whole story is much messier compared to LLVM. Which is actually fine, LLVM is much younger than GCC and could learn a lot from it. And GCC is still pretty great in the use cases it was intended for.
LLVM-IR has enabled this nice separation between the language front-end and the compilation back-end. GCC could have done that too: they didn't for political reasons. Why? Someone could have used GCC's C++ front-end for its proprietary compilation pipeline. Today this is nearly impossible to change in GCC.
There are also some other advantages for LLVM I like: it supports multiple architectures in a single binary. With GCC I need to compile the compiler either for x64 or arm but not both. GCC is still great but it's not surprising that LLVM is so successful.
I didn't make any claims about Java Applets or Flash performance.
Even if we would agree that the JVM is as good as WASM as a language-agnostic bytecode, WASM still makes sense since it doesn't come with all the baggage of the JVM like class files, many bytecodes that exactly match the Java semantics but can't be used in other languages. Browser-vendors would still have to add new bytecodes for common operations for both size and speed reasons. So it made sense to design a new bytecode format. WASM even allows streaming compilation: The browser can start compiling bytecode before it downloaded the whole file.
Yes, there are a few features missing from WASM. But just look how many applications have already been compiled for the web. The missing features are not that relevant for many large existing and performance-sensitive native applications written in C/C++. We don't need to rewrite this applications in JS. I mean JS wouldn't even be fast enough for that anyways. That's what WASM was designed for and even according to you WASM is better suited for this than Java-Bytecode.
Inline assembly and vector extensions would also be problematic in Java Bytecode.
There are very good technical reasons for WASMs existence. JVM-Bytecode for example is very Java-focused, WASM doesn't need class-files or many bytecodes like invokevirtual. For supporting C++/Rust it doesn't even need GC.
Bringing large applications like PSDFKit, AutoCAD or games into the browser is certainly getting the web forward. Sure, WASM isn't intended for manipulating the DOM. This is still JS's job (at least for the foreseeable future).
I don't think JVMs where without any security bugs, since WASM is mainly used in browsers right now, security is a MAJOR concern. Java-Bytecode was designed for a different purpose. Try to compile a language with multi-inheritance to Java-Bytecode, it's a pain. WASM is designed in a more language-agnostic way, that's why GC and Exception Handling is much harder to specify than in the JVM.
BTW: GC'ed languages can already be compiled to WASM: they more or less "just" need to compile the GC to WASM too. The GC proposal would only allow to reuse the embedder's (most likely the browser) GC.
AFAIK there is no Java-Bytecode involved for this and to optimize the AST-interpreter to something faster you need the Graal-Compiler, most JVMs can't do this. There is no C++/LLVM/Rust to Java-Bytecode compiler that is widely used, while this exists for WASM. Even a huge Codebase like AutoCAD was compiled for the Web. Java-Bytecode wasn't designed for this, you could theoretically do the same with Java-Bytecode but it would probably be much slower. Simply because Java-Bytecode wasn't designed for this purpose.
Java-Bytecode is notoriously hard to verify, WASM is more strict and therefore verification is easier. (With verification I mean the process in the Browser/JVM that checks if the bytecode is actually valid). WASM only allows structured control flow, no arbitrary gotos like Java. This makes the compilers job much easier, many JVMs actually just bail out on irreducible loops and therefore such code might not get optimized. OTOH WASM-Bytecode wasn't designed for interpretation.
I don't know why there is this heated discussion. WASM had the chance to learn from the mistakes in Java's Bytecode and both bytecodes were designed for different purposes after all. Java Bytecode was designed for Java, WASM for being a language-agnostic compilation target. Supporting GC in Java-Bytecode for example is much easier than having a similar thing in WASM.
> So they had a GC that scaled better. But it got killed by, you guessed it, the needs of batch jobs
Even in the JVM where you have multiple specialized GCs, the developers also look at each GC in workloads it wasn't designed for and that also seems to influence design decisions. For me this just means they focus on the server use case (=latency) but not at the cost of 50% throughput hit for the compiler (=batch job).
For implementing the generational GC they simply use sticky mark-bits.
Not arguing you should do such micro-optimizations, but generally writing "simpler" code should also allow less sophisticated compilers to generate fast code.
Bootstrap failures are taken very seriously by the GCC developers. So I really doubt that -g and -O* lead to non-deterministic builds.
Right now I am working from home which (after some months of experience) I enjoy much more. Also got a substantial pay raise when changing jobs and at the same time save money on the commute.
Still glad I was at my old job since it got me into another field of software engineering and I learned a lot. Don't think I would've got my current job without it.
The Permanent Generation was named that way since objects in there were never collected. For most applications this isn't really a problem. Running JRuby+Rails just allocated a lot of classes in this generation, so the default size was too small. But still, the permanent generation was quite small compared to the heap size.
I wouldn't really call the GC bad because of this, IMHO they were already quite good back then. And in Java 8 the permanent generation was replaced with the Metaspace, objects in there can be free'd and the Metaspace can be expanded at runtime so it's less likely to get these OOM errors for the permanent generation.
AFAIK there is some work on a GC in Rust, but it doesn't take away the borrow checker like you wished ;) So you will still need to use `.borrow()` and `.borrow_mut()`.
A language similar to Rust but with GC (and no borrow checker) could be quite useful for a lot of applications out there. Basically Go but a more "modern" language.
I was once working on a large project on the JVM: our Fat-JAR was really working on Linux, Mac and Windows. The exact same JAR. And it didn't matter on which system we have built that JAR. This may not be possible for every use case - but I don't think it is a hoax.
> It is not special, for script languages code runs anywhere without compiling.
IMHO scripting languages like Ruby, Python, etc. are quite hard to deploy, especially if they have dependencies. In comparison to languages like Java, Go or Rust.