y1yang0 / yvm

[yvm] low performance garbage-collectable jvm
MIT License
248 stars 55 forks source link

which version of jvm or any other version of jvm source code you referred for the development. #3

Open yiakwy opened 6 years ago

yiakwy commented 6 years ago

Background

By reviewing your implementation, I found that your initial codes including code execution for generic data type are all implemented using java.

I can not clearly see how did you build ast and convert them to op codes for the moment. But I think I can follow your submission step by step so that I can clearly see how you made changes.

But only 15 days ago: 04e75b5 -> racaljk committed on 4 Oct 2017, you changed all codes into c++ version when you wanted to implement a gc algorithm "mark and sweep".

It is a little bit like a full time project(java, c++ , 6 months project) rather than a project for demo, or for interests soly. Are you supported by any foundation or just writing it for fun?

I also noticed that you made a specific version of algorithm like RBTree, without delivering it as an independent package or library: no benchmark testing (you might be over confident to your implementation). At least I assume that you can rely on boost , google libraries for development: glog, boost.asio, boost.threads and so on.

here is what think about the programme

In YVM.cpp, your main thread creates a code execution engine for op code generated by some java semantic analyzer for a specific operating system (or some existing jvm? I am not clear about that). Then you create runtime "yrc" to load model and find execution entry point "main". When the main thread finishes codes execution, you fire gc(unreasonable).

I thought most of your efforts in 2017 is about implementing a loading relevant functions. After refactorization of your codes, your project does not have language relevant programmes like: symbol table, java language parser generator, and analyzer (ast). Have you tested octal, unicode parsing, it is not that trivial.

Question 1

How did you make sure that your line search over allocated memory blocks as java runtime frames stack living in heap, successfully be marked if the number of their refs' countered down to 0, and not marked if they don't. And then delete them if you have a scheduler

Question 2

Where do you manage different threads and pass mutex from parent to children thread? It seems that you don't have scheduler implementation for threads.

Question 3

Could you explain more about your ObjectMonitor.h/,cc? Generic object cast is a very challenging problem (@see python). I am curious about how you computed your memory block for type dynamic casting?

Question 4

For research complete, could you tell me, which version of java jvm or any other materials including c++ codes, java codes(your initial commit on some day in Sep, 2017) , you once referred for the project.

y1yang0 commented 6 years ago

This VM is pruely independent and I don't refered to any other JVM source code. Here my goal is to support the bytecode compiled by offical oracle Java compiler 1.6 to 1.9 , that is, this VM supported bytecode ranged from JDK6 to JDK9 (As you say, I haven't make a fully benchmark for my RBTree algorithm yet so I don't want to replace stl map with it.. This work would delay later, I reserve it as a dependent module.)

For your questions..

  1. I place the GC::gc() when the main thread finished since I just want to test it quickly and leave more work later (it's a bit late, I want to sleep..). You may confused Mark-and-Sweep with Reference Counting since there is no counting field for increasing/decreasing in mark-and-sweep algorithm.
  2. For simplicity, I lock the whole heap and there are only main thread and threads spawned by new Thread().start. We don't need a scheduler so far, a std::thread for creating 1:1 native thread is enough.
  3. ObjectMonitor.h was used to support the synchronization block syntax (synchronizd(obj){}). Now you can use synchronized(object){} to create a critical section and current executing thread would acquire the intrinsic object lock, but you can't declare a method with the synchronized keyword since I haven't finished it yet
  4. This project could divided into two parts, the first part started from the da68118 to 04e75b5, it's a semi-finished VM, we can not run Java program on it. And newer part started at 59c2f1e and I still work in progress so far, it's a runnable and somewhat useful VM. It was exactly written in c++ and also I rewrite some java code since it's necessary for its running and test programs for language features it supported.
yiakwy commented 6 years ago

Not only source code. Apparently you built it in your way from scratch. But that does not mean you build without any hints from any courses or projects. It becomes unreliable if you cannot figure out what's difference between your version and other's. And also, if somebody follows you with no idea how to develop a jvm, you might guide them into a wrong way to develop a that.

But any way, your effort is amazing.

y1yang0 commented 6 years ago

Thank your for your suggestion.

I'd write a detailed documentation of this VM about its architecture and all data structures for those who are interested in this project 😄

benyuereal commented 5 years ago

哥们 我用make -j4的时候 报错了 /Library/Developer/CommandLineTools/usr/include/c++/v1/unordered_map:392:11: error: call to implicitly-deleted default constructor of 'std::1::hash<std::1::basic_string >' : _Hash() {} ^

这个错误是由于我的环境问题吗 还是啥原因造成的 希望博主帮一下忙吧

y1yang0 commented 5 years ago

@benyuereal

调用了不存在的默认构造函数。

你的gcc版本是多少呢

benyuereal commented 5 years ago

苹果默认的gcc 我又在其他目录安装了一个gcc 添加了环境变量 但是当编译的时候说我自己安装的gcc不对

后来我就用了苹果默认的gcc版本 然后 make -j4的时候报错了,如下

NOTE: a missing vtable usually means the first non-inline virtual member function has no definition. "vtable for boost::program_options::value_semantic_codecvt_helper", referenced from: boost::program_options::value_semantic_codecvt_helper::value_semantic_codecvt_helper() in Main.cpp.o NOTE: a missing vtable usually means the first non-inline virtual member function has no definition. ld: symbol(s) not found for architecture x86_64 clang: error: linker command failed with exit code 1 (use -v to see invocation)

求助 咋办 骚年

y1yang0 commented 5 years ago

这个note看不出错误,最好贴一下gcc版本和boost版本

持续集成里的gcc7+boost_1_65_1在ubuntu上能通过编译,msvc2017也能在windows上通过,clang我还没测试过

benyuereal commented 5 years ago

我用的boost1.6.7和gcc8.1.0 mac电脑 最后的报错是这样的: ^ [100%] Linking CXX executable yvm Undefined symbols for architecture x86_64: "boost::program_options::to_internal(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&)", referenced from: std::vector<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::allocator<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > > > boost::program_options::to_internal<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >(std::vector<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::allocator<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > > > const&) in Main.cpp.o "boost::program_options::options_description::options_description(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, unsigned int, unsigned int)", referenced from: _main in Main.cpp.o "boost::program_options::invalid_option_value::invalid_option_value(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&)", referenced from: void boost::program_options::validate<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, char>(boost::any&, std::vector<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::allocator<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > > > const&, std::vector<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::allocator<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > > >*, int) in Main.cpp.o

我的配置文件是: ` cmake_minimum_required(VERSION 3.5) project(yvm)

set(CMAKE_CXX_STANDARD 14) if(UNIX) set(CMAKE_EXE_LINKER_FLAGS "-pthread") endif()

set(Boost_USE_STATIC_LIBS ON) set(Boost_USE_MULTITHREADED ON) set(BOOST_ROOT "/usr/local/Cellar/boost/1.67.0_1") find_package(Boost COMPONENTS system filesystem program_options)

if(Boost_FOUND) include_directories(${Boost_INCLUDE_DIRS}) set(SOURCE_FILES src/Main.cpp src/MethodArea.cpp src/Frame.h src/ClassFile.h src/AccessFlag.h src/RuntimeEnv.cpp src/NativeMethod.h src/CodeExecution.cpp src/Debug.cpp src/JavaClass.cpp src/JavaHeap.cpp src/JavaHeap.hpp src/CodeExecution.hpp src/NativeMethod.cpp src/YVM.cpp src/Utils.h src/Utils.cpp src/JavaException.h src/JavaException.cpp src/ObjectMonitor.h src/ObjectMonitor.cpp src/GC.h src/GC.cpp src/Option.h src/Concurrent.hpp src/Concurrent.cpp src/Internal.h) add_executable(yvm ${SOURCE_FILES}) link_directories(... ${Boost_LIBRARY_DIRS}) target_link_libraries(yvm ${Boost_LIBRARIES}) if(UNIX) target_link_libraries(yvm pthread) endif() endif()

enable_testing() file(GLOB test_file_name ${PROJECT_SOURCE_DIR}/javaclass/ydk/test/*.java)

if(WIN32)

add_test(NAME test_help COMMAND yvm --help)

foreach(each_file ${test_file_name}) string(REGEX REPLACE "./(.).java" "\1" curated_name ${each_file}) addtest(NAME test${curated_name} COMMAND yvm --runtime=${PROJECT_SOURCE_DIR}/bytecode "ydk.test.${curated_name}") endforeach(each_file ${test_file_name}) endif() `

帮我看看吧 谢谢啦

y1yang0 commented 5 years ago

老哥你的boost静态编译过吗

benyuereal commented 5 years ago

应该是静态编译过的 我用的 brew install boost命令安装的 应该这样的命令都是编译后的吧 可否加一下大兄弟的微信 我刚才给你发送了请求

y1yang0 commented 5 years ago

👍

215559085 commented 5 years ago

小学弟来瞻仰大佬了,我是java ee玩家看不懂jvm233。

tzh476 commented 4 years ago

This VM is pruely independent and I don't refered to any other JVM source code. Here my goal is to support the bytecode compiled by offical oracle Java compiler 1.6 to 1.9 , that is, this VM supported bytecode ranged from JDK6 to JDK9 (As you say, I haven't make a fully benchmark for my RBTree algorithm yet so I don't want to replace stl map with it.. This work would delay later, I reserve it as a dependent module.)

For your questions..

  1. I place the GC::gc() when the main thread finished since I just want to test it quickly and leave more work later (it's a bit late, I want to sleep..). You may confused Mark-and-Sweep with Reference Counting since there is no counting field for increasing/decreasing in mark-and-sweep algorithm.
  2. For simplicity, I lock the whole heap and there are only main thread and threads spawned by new Thread().start. We don't need a scheduler so far, a std::thread for creating 1:1 native thread is enough.
  3. ObjectMonitor.h was used to support the synchronization block syntax (synchronizd(obj){}). Now you can use synchronized(object){} to create a critical section and current executing thread would acquire the intrinsic object lock, but you can't declare a method with the synchronized keyword since I haven't finished it yet
  4. This project could divided into two parts, the first part started from the da68118 to 04e75b5, it's a semi-finished VM, we can not run Java program on it. And newer part started at 59c2f1e and I still work in progress so far, it's a runnable and somewhat useful VM. It was exactly written in c++ and also I rewrite some java code since it's necessary for its running and test programs for language features it supported.

It's a very clear explanation! About question 2, the current version dfa6fa6 has changed greatly from the previous version . For example, Concurrent.cppExecutorThreadPooltaskQueueMtxrunPendingWork()taskFutures are added to the project. Can you explain when a thread is created , how the ExecutorThreadPool works , and how mutex works in this process. Thank you!

yxbyxb commented 1 year ago

大佬我也好奇1楼问你的 这是全职项目还是兴趣使然 感觉很强

y1yang0 commented 1 year ago

大佬我也好奇1楼问你的 这是全职项目还是兴趣使然 感觉很强

Just for fun :-)

I thought it did not take much effort to build a "real jvm" after I finished classfile parsing. Since there could be a lot of direct memory manipulation, I rewrote the classfile parser in C++ due to its native-ness, then spent a little time implementing the rest of the interpreter and runtime. Have a good weekend.