OLD | NEW |
1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 the V8 project authors. All rights reserved. |
2 // Redistribution and use in source and binary forms, with or without | 2 // Redistribution and use in source and binary forms, with or without |
3 // modification, are permitted provided that the following conditions are | 3 // modification, are permitted provided that the following conditions are |
4 // met: | 4 // met: |
5 // | 5 // |
6 // * Redistributions of source code must retain the above copyright | 6 // * Redistributions of source code must retain the above copyright |
7 // notice, this list of conditions and the following disclaimer. | 7 // notice, this list of conditions and the following disclaimer. |
8 // * Redistributions in binary form must reproduce the above | 8 // * Redistributions in binary form must reproduce the above |
9 // copyright notice, this list of conditions and the following | 9 // copyright notice, this list of conditions and the following |
10 // disclaimer in the documentation and/or other materials provided | 10 // disclaimer in the documentation and/or other materials provided |
(...skipping 13 matching lines...) Expand all Loading... |
24 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | 24 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
25 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE | 25 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |
26 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | 26 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
27 | 27 |
28 #include <limits.h> | 28 #include <limits.h> |
29 | 29 |
30 #ifndef WIN32 | 30 #ifndef WIN32 |
31 #include <signal.h> // kill | 31 #include <signal.h> // kill |
32 #include <unistd.h> // getpid | 32 #include <unistd.h> // getpid |
33 #endif // WIN32 | 33 #endif // WIN32 |
| 34 #include <string> |
| 35 #include <map> |
34 | 36 |
35 #include "v8.h" | 37 #include "v8.h" |
36 | 38 |
37 #include "api.h" | 39 #include "api.h" |
38 #include "arguments.h" | 40 #include "arguments.h" |
39 #include "isolate.h" | 41 #include "isolate.h" |
40 #include "compilation-cache.h" | 42 #include "compilation-cache.h" |
41 #include "execution.h" | 43 #include "execution.h" |
42 #include "objects.h" | 44 #include "objects.h" |
43 #include "snapshot.h" | 45 #include "snapshot.h" |
(...skipping 12212 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
12256 v8::HandleScope outer(isolate); | 12258 v8::HandleScope outer(isolate); |
12257 v8::Local<Context> env = Context::New(isolate); | 12259 v8::Local<Context> env = Context::New(isolate); |
12258 env->Enter(); | 12260 env->Enter(); |
12259 v8::Handle<Value> value = NestedScope(env); | 12261 v8::Handle<Value> value = NestedScope(env); |
12260 v8::Handle<String> str(value->ToString()); | 12262 v8::Handle<String> str(value->ToString()); |
12261 CHECK(!str.IsEmpty()); | 12263 CHECK(!str.IsEmpty()); |
12262 env->Exit(); | 12264 env->Exit(); |
12263 } | 12265 } |
12264 | 12266 |
12265 | 12267 |
12266 static i::Handle<i::JSFunction>* foo_ptr = NULL; | 12268 static bool MatchPointers(void* key1, void* key2) { |
12267 static int foo_entry_count = 0; | 12269 return key1 == key2; |
12268 static i::Handle<i::JSFunction>* bar_ptr = NULL; | 12270 } |
12269 static int bar_entry_count = 0; | 12271 |
12270 static int bar_caller_count = 0; | 12272 |
12271 | 12273 struct SymbolInfo { |
12272 | 12274 size_t id; |
12273 static void entry_hook(uintptr_t function, | 12275 size_t size; |
12274 uintptr_t return_addr_location) { | 12276 std::string name; |
12275 i::Code* code = i::Code::GetCodeFromTargetAddress( | 12277 }; |
| 12278 |
| 12279 |
| 12280 class SetFunctionEntryHookTest { |
| 12281 public: |
| 12282 SetFunctionEntryHookTest() { |
| 12283 CHECK(instance_ == NULL); |
| 12284 instance_ = this; |
| 12285 } |
| 12286 ~SetFunctionEntryHookTest() { |
| 12287 CHECK(instance_ == this); |
| 12288 instance_ = NULL; |
| 12289 } |
| 12290 void Reset() { |
| 12291 symbols_.clear(); |
| 12292 symbol_locations_.clear(); |
| 12293 invocations_.clear(); |
| 12294 } |
| 12295 void RunTest(); |
| 12296 void OnJitEvent(const v8::JitCodeEvent* event); |
| 12297 static void JitEvent(const v8::JitCodeEvent* event) { |
| 12298 CHECK(instance_ != NULL); |
| 12299 instance_->OnJitEvent(event); |
| 12300 } |
| 12301 |
| 12302 void OnEntryHook(uintptr_t function, |
| 12303 uintptr_t return_addr_location); |
| 12304 static void EntryHook(uintptr_t function, |
| 12305 uintptr_t return_addr_location) { |
| 12306 CHECK(instance_ != NULL); |
| 12307 instance_->OnEntryHook(function, return_addr_location); |
| 12308 } |
| 12309 |
| 12310 static void RuntimeCallback(const v8::FunctionCallbackInfo<v8::Value>& args) { |
| 12311 CHECK(instance_ != NULL); |
| 12312 args.GetReturnValue().Set(v8_num(42)); |
| 12313 } |
| 12314 void RunLoopInNewEnv(v8::Isolate* isolate); |
| 12315 |
| 12316 // Records addr as location of symbol. |
| 12317 void InsertSymbolAt(i::Address addr, SymbolInfo* symbol); |
| 12318 |
| 12319 // Finds the symbol containing addr |
| 12320 SymbolInfo* FindSymbolForAddr(i::Address addr); |
| 12321 // Returns the number of invocations where the caller name contains |
| 12322 // \p caller_name and the function name contains \p function_name. |
| 12323 int CountInvocations(const char* caller_name, |
| 12324 const char* function_name); |
| 12325 |
| 12326 i::Handle<i::JSFunction> foo_func_; |
| 12327 i::Handle<i::JSFunction> bar_func_; |
| 12328 |
| 12329 typedef std::map<size_t, SymbolInfo> SymbolMap; |
| 12330 typedef std::map<i::Address, SymbolInfo*> SymbolLocationMap; |
| 12331 typedef std::map<std::pair<SymbolInfo*, SymbolInfo*>, int> InvocationMap; |
| 12332 SymbolMap symbols_; |
| 12333 SymbolLocationMap symbol_locations_; |
| 12334 InvocationMap invocations_; |
| 12335 |
| 12336 static SetFunctionEntryHookTest* instance_; |
| 12337 }; |
| 12338 SetFunctionEntryHookTest* SetFunctionEntryHookTest::instance_ = NULL; |
| 12339 |
| 12340 |
| 12341 // Returns true if addr is in the range [start, start+len). |
| 12342 static bool Overlaps(i::Address start, size_t len, i::Address addr) { |
| 12343 if (start <= addr && start + len > addr) |
| 12344 return true; |
| 12345 |
| 12346 return false; |
| 12347 } |
| 12348 |
| 12349 void SetFunctionEntryHookTest::InsertSymbolAt(i::Address addr, |
| 12350 SymbolInfo* symbol) { |
| 12351 // Insert the symbol at the new location. |
| 12352 SymbolLocationMap::iterator it = |
| 12353 symbol_locations_.insert(std::make_pair(addr, symbol)).first; |
| 12354 // Now erase symbols to the left and right that overlap this one. |
| 12355 while (it != symbol_locations_.begin()) { |
| 12356 SymbolLocationMap::iterator left = it; |
| 12357 --left; |
| 12358 if (!Overlaps(left->first, left->second->size, addr)) |
| 12359 break; |
| 12360 symbol_locations_.erase(left); |
| 12361 } |
| 12362 |
| 12363 // Now erase symbols to the left and right that overlap this one. |
| 12364 while (true) { |
| 12365 SymbolLocationMap::iterator right = it; |
| 12366 ++right; |
| 12367 if (right == symbol_locations_.end()) |
| 12368 break; |
| 12369 if (!Overlaps(addr, symbol->size, right->first)) |
| 12370 break; |
| 12371 symbol_locations_.erase(right); |
| 12372 } |
| 12373 } |
| 12374 |
| 12375 |
| 12376 void SetFunctionEntryHookTest::OnJitEvent(const v8::JitCodeEvent* event) { |
| 12377 switch (event->type) { |
| 12378 case v8::JitCodeEvent::CODE_ADDED: { |
| 12379 CHECK(event->code_start != NULL); |
| 12380 CHECK_NE(0, static_cast<int>(event->code_len)); |
| 12381 CHECK(event->name.str != NULL); |
| 12382 size_t symbol_id = symbols_.size(); |
| 12383 |
| 12384 // Record the new symbol. |
| 12385 SymbolInfo& info = symbols_[symbol_id]; |
| 12386 info.id = symbol_id; |
| 12387 info.size = event->code_len; |
| 12388 info.name.assign(event->name.str, event->name.str + event->name.len); |
| 12389 |
| 12390 // And record it's location. |
| 12391 InsertSymbolAt(reinterpret_cast<i::Address>(event->code_start), &info); |
| 12392 } |
| 12393 break; |
| 12394 |
| 12395 case v8::JitCodeEvent::CODE_MOVED: { |
| 12396 // We would like to never see code move that we haven't seen before, |
| 12397 // but the code creation event does not happen until the line endings |
| 12398 // have been calculated (this is so that we can report the line in the |
| 12399 // script at which the function source is found, see |
| 12400 // Compiler::RecordFunctionCompilation) and the line endings |
| 12401 // calculations can cause a GC, which can move the newly created code |
| 12402 // before its existence can be logged. |
| 12403 SymbolLocationMap::iterator it( |
| 12404 symbol_locations_.find( |
| 12405 reinterpret_cast<i::Address>(event->code_start))); |
| 12406 if (it != symbol_locations_.end()) { |
| 12407 // Found a symbol at this location, move it. |
| 12408 SymbolInfo* info = it->second; |
| 12409 symbol_locations_.erase(it); |
| 12410 InsertSymbolAt(reinterpret_cast<i::Address>(event->new_code_start), |
| 12411 info); |
| 12412 } |
| 12413 } |
| 12414 default: |
| 12415 break; |
| 12416 } |
| 12417 } |
| 12418 |
| 12419 void SetFunctionEntryHookTest::OnEntryHook( |
| 12420 uintptr_t function, uintptr_t return_addr_location) { |
| 12421 // Get the function's code object. |
| 12422 i::Code* function_code = i::Code::GetCodeFromTargetAddress( |
12276 reinterpret_cast<i::Address>(function)); | 12423 reinterpret_cast<i::Address>(function)); |
12277 CHECK(code != NULL); | 12424 CHECK(function_code != NULL); |
12278 | 12425 |
12279 if (bar_ptr != NULL && code == (*bar_ptr)->code()) | 12426 // Then try and look up the caller's code object. |
12280 ++bar_entry_count; | 12427 i::Address caller = *reinterpret_cast<i::Address*>(return_addr_location); |
12281 | 12428 |
12282 if (foo_ptr != NULL && code == (*foo_ptr)->code()) | 12429 // Count the invocation. |
12283 ++foo_entry_count; | 12430 SymbolInfo* caller_symbol = FindSymbolForAddr(caller); |
12284 | 12431 SymbolInfo* function_symbol = |
12285 // Let's check whether bar is the caller. | 12432 FindSymbolForAddr(reinterpret_cast<i::Address>(function)); |
12286 if (bar_ptr != NULL) { | 12433 ++invocations_[std::make_pair(caller_symbol, function_symbol)]; |
12287 const v8::internal::byte* caller = | 12434 |
12288 *reinterpret_cast<v8::internal::byte**>(return_addr_location); | 12435 if (!bar_func_.is_null() && function_code == bar_func_->code()) { |
12289 | 12436 // Check that we have a symbol for the "bar" function at the right location. |
12290 if ((*bar_ptr)->code()->instruction_start() <= caller && | 12437 SymbolLocationMap::iterator it( |
12291 (*bar_ptr)->code()->instruction_end() > caller) { | 12438 symbol_locations_.find(function_code->instruction_start())); |
12292 ++bar_caller_count; | 12439 CHECK(it != symbol_locations_.end()); |
| 12440 } |
| 12441 |
| 12442 if (!foo_func_.is_null() && function_code == foo_func_->code()) { |
| 12443 // Check that we have a symbol for "foo" at the right location. |
| 12444 SymbolLocationMap::iterator it( |
| 12445 symbol_locations_.find(function_code->instruction_start())); |
| 12446 CHECK(it != symbol_locations_.end()); |
| 12447 } |
| 12448 } |
| 12449 |
| 12450 |
| 12451 SymbolInfo* SetFunctionEntryHookTest::FindSymbolForAddr(i::Address addr) { |
| 12452 SymbolLocationMap::iterator it(symbol_locations_.lower_bound(addr)); |
| 12453 // Do we have a direct hit on a symbol? |
| 12454 if (it != symbol_locations_.end()) { |
| 12455 if (it->first == addr) |
| 12456 return it->second; |
| 12457 } |
| 12458 |
| 12459 // If not a direct hit, it'll have to be the previous symbol. |
| 12460 if (it == symbol_locations_.begin()) |
| 12461 return NULL; |
| 12462 |
| 12463 --it; |
| 12464 size_t offs = addr - it->first; |
| 12465 if (offs < it->second->size) |
| 12466 return it->second; |
| 12467 |
| 12468 return NULL; |
| 12469 } |
| 12470 |
| 12471 |
| 12472 int SetFunctionEntryHookTest::CountInvocations( |
| 12473 const char* caller_name, const char* function_name) { |
| 12474 InvocationMap::iterator it(invocations_.begin()); |
| 12475 int invocations = 0; |
| 12476 for (; it != invocations_.end(); ++it) { |
| 12477 SymbolInfo* caller = it->first.first; |
| 12478 SymbolInfo* function = it->first.second; |
| 12479 |
| 12480 // Filter out non-matching functions. |
| 12481 if (function_name != NULL) { |
| 12482 if (function->name.find(function_name) == std::string::npos) |
| 12483 continue; |
12293 } | 12484 } |
12294 } | 12485 |
12295 } | 12486 // Filter out non-matching callers. |
12296 | 12487 if (caller_name != NULL) { |
12297 | 12488 if (caller == NULL) |
12298 static void RunLoopInNewEnv() { | 12489 continue; |
12299 bar_ptr = NULL; | 12490 if (caller->name.find(caller_name) == std::string::npos) |
12300 foo_ptr = NULL; | 12491 continue; |
12301 | 12492 } |
12302 v8::Isolate* isolate = v8::Isolate::GetCurrent(); | 12493 |
| 12494 // It matches add the invocation count to the tally. |
| 12495 invocations += it->second; |
| 12496 } |
| 12497 |
| 12498 return invocations; |
| 12499 } |
| 12500 |
| 12501 |
| 12502 void SetFunctionEntryHookTest::RunLoopInNewEnv(v8::Isolate* isolate) { |
12303 v8::HandleScope outer(isolate); | 12503 v8::HandleScope outer(isolate); |
12304 v8::Local<Context> env = Context::New(isolate); | 12504 v8::Local<Context> env = Context::New(isolate); |
12305 env->Enter(); | 12505 env->Enter(); |
12306 | 12506 |
| 12507 Local<ObjectTemplate> t = ObjectTemplate::New(); |
| 12508 t->Set(v8_str("asdf"), v8::FunctionTemplate::New(RuntimeCallback)); |
| 12509 env->Global()->Set(v8_str("obj"), t->NewInstance()); |
| 12510 |
12307 const char* script = | 12511 const char* script = |
12308 "function bar() {" | 12512 "function bar() {\n" |
12309 " var sum = 0;" | 12513 " var sum = 0;\n" |
12310 " for (i = 0; i < 100; ++i)" | 12514 " for (i = 0; i < 100; ++i)\n" |
12311 " sum = foo(i);" | 12515 " sum = foo(i);\n" |
12312 " return sum;" | 12516 " return sum;\n" |
12313 "}" | 12517 "}\n" |
12314 "function foo(i) { return i * i; }"; | 12518 "function foo(i) { return i * i; }\n" |
| 12519 "// Invoke on the runtime function.\n" |
| 12520 "obj.asdf()"; |
12315 CompileRun(script); | 12521 CompileRun(script); |
12316 i::Handle<i::JSFunction> bar = | 12522 bar_func_ = i::Handle<i::JSFunction>::cast( |
12317 i::Handle<i::JSFunction>::cast( | |
12318 v8::Utils::OpenHandle(*env->Global()->Get(v8_str("bar")))); | 12523 v8::Utils::OpenHandle(*env->Global()->Get(v8_str("bar")))); |
12319 ASSERT(*bar); | 12524 ASSERT(!bar_func_.is_null()); |
12320 | 12525 |
12321 i::Handle<i::JSFunction> foo = | 12526 foo_func_ = |
12322 i::Handle<i::JSFunction>::cast( | 12527 i::Handle<i::JSFunction>::cast( |
12323 v8::Utils::OpenHandle(*env->Global()->Get(v8_str("foo")))); | 12528 v8::Utils::OpenHandle(*env->Global()->Get(v8_str("foo")))); |
12324 ASSERT(*foo); | 12529 ASSERT(!foo_func_.is_null()); |
12325 | |
12326 bar_ptr = &bar; | |
12327 foo_ptr = &foo; | |
12328 | 12530 |
12329 v8::Handle<v8::Value> value = CompileRun("bar();"); | 12531 v8::Handle<v8::Value> value = CompileRun("bar();"); |
12330 CHECK(value->IsNumber()); | 12532 CHECK(value->IsNumber()); |
12331 CHECK_EQ(9801.0, v8::Number::Cast(*value)->Value()); | 12533 CHECK_EQ(9801.0, v8::Number::Cast(*value)->Value()); |
12332 | 12534 |
12333 // Test the optimized codegen path. | 12535 // Test the optimized codegen path. |
12334 value = CompileRun("%OptimizeFunctionOnNextCall(foo);" | 12536 value = CompileRun("%OptimizeFunctionOnNextCall(foo);" |
12335 "bar();"); | 12537 "bar();"); |
12336 CHECK(value->IsNumber()); | 12538 CHECK(value->IsNumber()); |
12337 CHECK_EQ(9801.0, v8::Number::Cast(*value)->Value()); | 12539 CHECK_EQ(9801.0, v8::Number::Cast(*value)->Value()); |
12338 | 12540 |
12339 env->Exit(); | 12541 env->Exit(); |
12340 } | 12542 } |
12341 | 12543 |
| 12544 void SetFunctionEntryHookTest::RunTest() { |
| 12545 // Work in a new isolate throughout. |
| 12546 v8::Isolate* isolate = v8::Isolate::New(); |
| 12547 |
| 12548 // Test setting the entry hook on the new isolate. |
| 12549 CHECK(v8::V8::SetFunctionEntryHook(isolate, EntryHook)); |
| 12550 |
| 12551 // Replacing the hook, once set should fail. |
| 12552 CHECK_EQ(false, v8::V8::SetFunctionEntryHook(isolate, EntryHook)); |
| 12553 |
| 12554 { |
| 12555 v8::Isolate::Scope scope(isolate); |
| 12556 |
| 12557 v8::V8::SetJitCodeEventHandler(v8::kJitCodeEventDefault, JitEvent); |
| 12558 |
| 12559 RunLoopInNewEnv(isolate); |
| 12560 |
| 12561 // Check the exepected invocation counts. |
| 12562 CHECK_EQ(2, CountInvocations(NULL, "bar")); |
| 12563 CHECK_EQ(200, CountInvocations("bar", "foo")); |
| 12564 CHECK_EQ(200, CountInvocations(NULL, "foo")); |
| 12565 |
| 12566 // Verify that we have an entry hook on some specific stubs. |
| 12567 CHECK_NE(0, CountInvocations(NULL, "CEntryStub")); |
| 12568 CHECK_NE(0, CountInvocations(NULL, "JSEntryStub")); |
| 12569 CHECK_NE(0, CountInvocations(NULL, "JSEntryTrampoline")); |
| 12570 } |
| 12571 isolate->Dispose(); |
| 12572 |
| 12573 Reset(); |
| 12574 |
| 12575 // Make sure a second isolate is unaffected by the previous entry hook. |
| 12576 isolate = v8::Isolate::New(); |
| 12577 { |
| 12578 v8::Isolate::Scope scope(isolate); |
| 12579 |
| 12580 // Reset the entry count to zero and set the entry hook. |
| 12581 RunLoopInNewEnv(isolate); |
| 12582 |
| 12583 // We should record no invocations in this isolate. |
| 12584 CHECK_EQ(0, static_cast<int>(invocations_.size())); |
| 12585 } |
| 12586 // Since the isolate has been used, we shouldn't be able to set an entry |
| 12587 // hook anymore. |
| 12588 CHECK_EQ(false, v8::V8::SetFunctionEntryHook(isolate, EntryHook)); |
| 12589 |
| 12590 isolate->Dispose(); |
| 12591 } |
| 12592 |
12342 | 12593 |
12343 TEST(SetFunctionEntryHook) { | 12594 TEST(SetFunctionEntryHook) { |
12344 // FunctionEntryHook does not work well with experimental natives. | 12595 // FunctionEntryHook does not work well with experimental natives. |
12345 // Experimental natives are compiled during snapshot deserialization. | 12596 // Experimental natives are compiled during snapshot deserialization. |
12346 // This test breaks because InstallGetter (function from snapshot that | 12597 // This test breaks because InstallGetter (function from snapshot that |
12347 // only gets called from experimental natives) is compiled with entry hooks. | 12598 // only gets called from experimental natives) is compiled with entry hooks. |
12348 i::FLAG_harmony_typed_arrays = false; | 12599 i::FLAG_harmony_typed_arrays = false; |
12349 i::FLAG_harmony_array_buffer = false; | 12600 i::FLAG_harmony_array_buffer = false; |
12350 | 12601 |
12351 i::FLAG_allow_natives_syntax = true; | 12602 i::FLAG_allow_natives_syntax = true; |
12352 i::FLAG_use_inlining = false; | 12603 i::FLAG_use_inlining = false; |
12353 | 12604 |
12354 // Test setting and resetting the entry hook. | 12605 SetFunctionEntryHookTest test; |
12355 // Nulling it should always succeed. | 12606 test.RunTest(); |
12356 CHECK(v8::V8::SetFunctionEntryHook(NULL)); | |
12357 | |
12358 CHECK(v8::V8::SetFunctionEntryHook(entry_hook)); | |
12359 // Setting a hook while one's active should fail. | |
12360 CHECK_EQ(false, v8::V8::SetFunctionEntryHook(entry_hook)); | |
12361 | |
12362 CHECK(v8::V8::SetFunctionEntryHook(NULL)); | |
12363 | |
12364 // Reset the entry count to zero and set the entry hook. | |
12365 bar_entry_count = 0; | |
12366 bar_caller_count = 0; | |
12367 foo_entry_count = 0; | |
12368 CHECK(v8::V8::SetFunctionEntryHook(entry_hook)); | |
12369 RunLoopInNewEnv(); | |
12370 | |
12371 CHECK_EQ(2, bar_entry_count); | |
12372 CHECK_EQ(200, bar_caller_count); | |
12373 CHECK_EQ(200, foo_entry_count); | |
12374 | |
12375 // Clear the entry hook and count. | |
12376 bar_entry_count = 0; | |
12377 bar_caller_count = 0; | |
12378 foo_entry_count = 0; | |
12379 v8::V8::SetFunctionEntryHook(NULL); | |
12380 | |
12381 // Clear the compilation cache to make sure we don't reuse the | |
12382 // functions from the previous invocation. | |
12383 v8::internal::Isolate::Current()->compilation_cache()->Clear(); | |
12384 | |
12385 // Verify that entry hooking is now disabled. | |
12386 RunLoopInNewEnv(); | |
12387 CHECK_EQ(0u, bar_entry_count); | |
12388 CHECK_EQ(0u, bar_caller_count); | |
12389 CHECK_EQ(0u, foo_entry_count); | |
12390 } | 12607 } |
12391 | 12608 |
12392 | 12609 |
12393 static i::HashMap* code_map = NULL; | 12610 static i::HashMap* code_map = NULL; |
12394 static i::HashMap* jitcode_line_info = NULL; | 12611 static i::HashMap* jitcode_line_info = NULL; |
12395 static int saw_bar = 0; | 12612 static int saw_bar = 0; |
12396 static int move_events = 0; | 12613 static int move_events = 0; |
12397 | 12614 |
12398 | 12615 |
12399 static bool FunctionNameIs(const char* expected, | 12616 static bool FunctionNameIs(const char* expected, |
(...skipping 121 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
12521 break; | 12738 break; |
12522 | 12739 |
12523 default: | 12740 default: |
12524 // Impossible event. | 12741 // Impossible event. |
12525 CHECK(false); | 12742 CHECK(false); |
12526 break; | 12743 break; |
12527 } | 12744 } |
12528 } | 12745 } |
12529 | 12746 |
12530 | 12747 |
12531 static bool MatchPointers(void* key1, void* key2) { | |
12532 return key1 == key2; | |
12533 } | |
12534 | |
12535 | |
12536 TEST(SetJitCodeEventHandler) { | 12748 TEST(SetJitCodeEventHandler) { |
12537 i::FLAG_stress_compaction = true; | 12749 i::FLAG_stress_compaction = true; |
12538 i::FLAG_incremental_marking = false; | 12750 i::FLAG_incremental_marking = false; |
12539 const char* script = | 12751 const char* script = |
12540 "function bar() {" | 12752 "function bar() {" |
12541 " var sum = 0;" | 12753 " var sum = 0;" |
12542 " for (i = 0; i < 100; ++i)" | 12754 " for (i = 0; i < 100; ++i)" |
12543 " sum = foo(i);" | 12755 " sum = foo(i);" |
12544 " return sum;" | 12756 " return sum;" |
12545 "}" | 12757 "}" |
(...skipping 6802 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
19348 i::Semaphore* sem_; | 19560 i::Semaphore* sem_; |
19349 volatile int sem_value_; | 19561 volatile int sem_value_; |
19350 }; | 19562 }; |
19351 | 19563 |
19352 | 19564 |
19353 THREADED_TEST(SemaphoreInterruption) { | 19565 THREADED_TEST(SemaphoreInterruption) { |
19354 ThreadInterruptTest().RunTest(); | 19566 ThreadInterruptTest().RunTest(); |
19355 } | 19567 } |
19356 | 19568 |
19357 #endif // WIN32 | 19569 #endif // WIN32 |
OLD | NEW |