V8 是 JavaScript 引擎,采用 C++ 编写,在 Google 的 Chrome 浏览器中被使用。V8 引擎可以独立运行,也可以用来嵌入到 C++ 应用程序中执行。
V8在运行之前将JavaScript编译成了机器码,而非字节码或是直译它,以此提升性能。更进一步,使用了如内联缓存(inline caching)等方法来提高性能。有了这些功能,JavaScript程序与V8引擎的速度媲美二进制编译。传统的javascript是动态语言, 又可称之为 Prototype-based Language,JavaScript继承方法是使用prototype, 通过指定prototype属性,便可以指定要继承的目标。属性可以在运行时添加到或从对象中删除,引擎会为运行中的对象创建一个属性字典,新的属性都要通过字典查找属性在内存中的位置。V8为object新增属性的时候,就以上次的hidden class为父类别,创建新属性的hidden class的子类别,如此一来属性访问不再需要动态字典查找了。为了缩短由垃圾收集造成的停顿,V8 使用stop-the-world, generational, accurate 的垃圾收集器。在执行回收之时会暂时中断程序的执行,而且只处理对象堆栈。还会收集内存内所有对象的指针,可以避免内存溢出的情况。V8汇编器是基于Strongtalk汇编器。
项目如图:
v8测试代码:
int main(int argc, char* argv[]) { return v8::Shell::Main(argc, argv); }
int main(int argc, char* argv[]) { v8::internal::FlagList::SetFlagsFromCommandLine(&argc, argv, true); int tests_run = 0; bool print_run_count = true; for (int i = 1; i < argc; i++) { char* arg = argv[i]; if (strcmp(arg, "--list") == 0) { PrintTestList(CcTest::last()); print_run_count = false; } else { char* arg_copy = v8::internal::StrDup(arg); char* testname = strchr(arg_copy, '/'); if (testname) { // Split the string in two by nulling the slash and then run // exact matches. *testname = 0; char* file = arg_copy; char* name = testname + 1; CcTest* test = CcTest::last(); while (test != NULL) { if (test->enabled() && strcmp(test->file(), file) == 0 && strcmp(test->name(), name) == 0) { test->Run(); tests_run++; } test = test->prev(); } } else { // Run all tests with the specified file or test name. char* file_or_name = arg_copy; CcTest* test = CcTest::last(); while (test != NULL) { if (test->enabled() && (strcmp(test->file(), file_or_name) == 0 || strcmp(test->name(), file_or_name) == 0)) { test->Run(); tests_run++; } test = test->prev(); } } v8::internal::DeleteArray<char>(arg_copy); } } if (print_run_count && tests_run != 1) printf("Ran %i tests.\n", tests_run); v8::V8::Dispose(); return 0; }
int main(int argc, char** argv) { #ifdef ENABLE_LOGGING_AND_PROFILING // By default, log code create information in the snapshot. i::FLAG_log_code = true; #endif // Print the usage if an error occurs when parsing the command line // flags or if the help flag is set. int result = i::FlagList::SetFlagsFromCommandLine(&argc, argv, true); if (result > 0 || argc != 2 || i::FLAG_help) { ::printf("Usage: %s [flag] ... outfile\n", argv[0]); i::FlagList::PrintHelp(); return !i::FLAG_help; } v8::V8::SetCounterFunction(counter_callback); v8::HandleScope scope; const int kExtensionCount = 1; const char* extension_list[kExtensionCount] = { "v8/gc" }; v8::ExtensionConfiguration extensions(kExtensionCount, extension_list); i::Serializer::Enable(); v8::Context::New(&extensions); // Make sure all builtin scripts are cached. { HandleScope scope; for (int i = 0; i < i::Natives::GetBuiltinsCount(); i++) { i::Bootstrapper::NativesSourceLookup(i); } } // Get rid of unreferenced scripts with a global GC. i::Heap::CollectAllGarbage(); i::Serializer ser; ser.Serialize(); v8::internal::byte* bytes; int len; ser.Finalize(&bytes, &len); WriteInternalSnapshotToFile(argv[1], bytes, len); i::DeleteArray(bytes); return 0; }
int main(int argc, char* argv[]) { map<string, string> options; string file; ParseOptions(argc, argv, options, &file); if (file.empty()) { fprintf(stderr, "No script was specified.\n"); return 1; } HandleScope scope; Handle<String> source = ReadFile(file); if (source.IsEmpty()) { fprintf(stderr, "Error reading '%s'.\n", file.c_str()); return 1; } JsHttpRequestProcessor processor(source); map<string, string> output; if (!processor.Initialize(&options, &output)) { fprintf(stderr, "Error initializing processor.\n"); return 1; } if (!ProcessEntries(&processor, kSampleSize, kSampleRequests)) return 1; PrintMap(&output); }
int main(int argc, char* argv[]) { int result = RunMain(argc, argv); v8::V8::Dispose(); return result; }
效果如图:
学习的目标是成熟!~~~