GithubHelp home page GithubHelp logo

Comments (11)

kripken avatar kripken commented on July 24, 2024

It is easy to add this, just include the dlmalloc.c source code file (in tests/) with your source code (without the main() at the bottom there which is just the test_dlmalloc test). Emscripten will then use the real malloc/free implemented in this file instead of the stubs.

We could make this easier I guess, with a parameter to emscripten.py that optionally includes dlmalloc?

from emscripten.

max99x avatar max99x commented on July 24, 2024

Yeah, I would say making this more obvious and easy to access is rather important. Why is it not the default? Simply to simplify debugging or does it impact performance?

from emscripten.

kripken avatar kripken commented on July 24, 2024

It definitely impacts compiling performance, that's the main reason it isn't used by default.

Runtime performance is perhaps slightly slower, but not significantly (dlmalloc is in the emscripten benchmark suite, we are about 5X slower than native code on it, so it is fairly fast).

from emscripten.

max99x avatar max99x commented on July 24, 2024

Then I'll try adding an option for it to settings.js tomorrow.

from emscripten.

kripken avatar kripken commented on July 24, 2024

One concern I have is about where to add this.

Adding it in settings.js won't work I think, since this needs to be done at the level of C/C++ source code or .bc. The reason is that while we could try to add malloc/free to library.js, but it's more than those two functions, dlmalloc has various globals. Letting llvm do the linking is much safer and easier.

We could add it to emscripten.py, but it gets .ll so it would need to convert the .ll to .bc, then link with dlmalloc, then reconvert to .ll, which isn't very efficient. However, it might be worth doing that, another benefit we could get from writing that code is we could also detect if the .ll did not have -show-annotations, and recompile to .bc in order to get that. We might also let emscripten.py get .bc and convert that to .ll while we are at it.

from emscripten.

max99x avatar max99x commented on July 24, 2024

Having dlmalloc stored in a .bc and linking it in emscripten.py with the passed file when something like a --with-dlmalloc is passed sounds good to me. I'll be happy to handle writing that. While we're at it, it would be easy to also add an option to run the LLVM optimization pass.

from emscripten.

kripken avatar kripken commented on July 24, 2024

One concern though is that llvm .bc files are not platform independent. Emscripten does for simplicity assume a 32-bit architecture (since JS is skewed towards that), so we aren't platform-independent already. However, I wouldn't want to add additional dependencies. For example, it isn't clear that a 32-bit x86 .bc would work on 32-bit ARM.

Instead, how about adding this as an option to emmaken. Basically, make emmaken compile and link in dlmalloc when asked to. However, emmaken would need to figure out when the final linking stage is, so this might not work for all projects.

from emscripten.

max99x avatar max99x commented on July 24, 2024

I feel that pushing a core element like memory management all the way out to emmaken.py makes for quite clumsy usage and will cause a lot of headaches for cases where emmaken isn't used.

I guess my question is, is there a reason to care about ARM? After all, the end result is platform-independent anyway, while emscripten itself assumes a whole lot about the environment (e.g. right now requires Linux, LLVM, Python and v8/tracemonkey). If the user has ARM-targeted bytecode, they probably have source code as well, and if their machine can run emscripten, chances are they can recompile for x86 as well; we're already blocking x86-64, and that's certainly more common than ARM.

I would say having a simple and reliable malloc is significantly more practical than catering for the possibility of running emscripten itself on multiple platforms.

from emscripten.

kripken avatar kripken commented on July 24, 2024

I see your point. It isn't just ARM though, it might not work on OS X x86 either. LLVM bitcode is very platform dependent.

But again, I agree with your point, we need a better solution. So, looks like adding it to emscripten.py is the right way. It will need to convert the input.ll to bc, compile dlmalloc into bc, llvm-link them, llvm-dis, then compile that. Not hard to do though. And as mentioned earlier, as a side benefit we get -show-annotations guaranteed.

from emscripten.

max99x avatar max99x commented on July 24, 2024

Ok, I wrote a basic version of this (commited in my fork). A few problems:

  1. Emscripting a file that was linked with dlmalloc and optimized using opt -O3 produces an error:

    Assertion failed: What variable is this? |4|
    Stack: Error
        at assertTrue (utility.js:60:23)
        at getVarImpl (jsifier.js:492:5)
        at jsifier.js:691:29
        at Object.processItem (jsifier.js:552:19)
        at Object.process (framework.js:155:26)
        at framework.js:104:25
        at Array.forEach (native)
        at Object.solve (framework.js:92:27)
        at JSify (jsifier.js:850:34)
        at JSify (jsifier.js:54:15)
    utility.js:61: Assertion failed: What variable is this? |4|
        throw msg;
        ^
    

    Is this expected? Should we have separate optimization passes for dlmalloc? Example LL.

  2. The new version of emscripten.py reassembles any passed .ll and disassembles it back to make sure it has annotations. This appears to cause several problems. When running llvm_gcc_0_0.test_cases, I'm getting the following error:

    Testing case '/home/max/emscripten-workspace/emscripten/tests/cases/extendedprecision'...
    /home/max/emscripten-workspace/llvm-build/Release/bin/llvm-as: /dev/shm/tmp/src.cpp.o.ll:10:17: error: constant expression type mismatch
      %0 = call i32 bitcast (i32 (i8*)* @puts to i32 (i32*)*)(i8* getelementptr inbounds ([14 x i8]* @.str, i32 0, i32 0)) ; [#uses=0]
    

    Running llvm-as manually on extendedprecision.ll produces the same error. Similarly, llvm_gcc_0_0.test_if produces:

    /home/max/emscripten-workspace/llvm-build/Release/bin/llvm-as: /dev/shm/tmp/src.cpp.o.ll:16:23: error: invalid use of function-local name
      br i1 icmp sgt (i32 %1, i32 3), label %bb, label %bb1
                          ^
    

    On clang test_cases is disabled while test_if works fine. Looks like another case of llvm-dis not being 100% compatible with llvm-as. Can you reproduce the error (by running llvm-as on extendedprecision.ll)? Any ideas what the exact cause is, and if there is a workaround?

from emscripten.

kripken avatar kripken commented on July 24, 2024
  1. llvm-opt can generate nonportable code. In this case, the output is
  %.pre18.i.i = load i32* inttoptr (i32 4 to i32*), align 4 ; [#uses=1]

It looks like it's loading from absolute address 4. Not sure exactly why it thought that was a good idea.

The test runner uses a safe subset of llvm optimizations (pick_llvm_opts). We should probably move that to shared.py, and use it in both the test runner and emscripten.py. (And eventually improve it, issue 21.)

  1. test_cases contains files that may be invalid .ll - they are only well-formed enough for us to run a test on them, not for llvm to parse them. Also, the point there is for us to parse that exact .ll, since llvm-as/llvm-dis may change the output and remove/reshape the part that caused the original bug. I'll add a clarifying comment.

In any case, I think the default in emscripten.py should be to just process the given .ll, and not run it through llvm-dis and llvm-as (unless we actually need to - for dlmalloc, or if we detect that -show-annotations has not been run), because otherwise it's a lot of unneeded CPU work. So the .ll in test_cases should not end up being processed by llvm-as.

from emscripten.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.