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> | |
36 | 34 |
37 #include "v8.h" | 35 #include "v8.h" |
38 | 36 |
39 #include "api.h" | 37 #include "api.h" |
40 #include "arguments.h" | 38 #include "arguments.h" |
41 #include "isolate.h" | 39 #include "isolate.h" |
42 #include "compilation-cache.h" | 40 #include "compilation-cache.h" |
43 #include "execution.h" | 41 #include "execution.h" |
44 #include "objects.h" | 42 #include "objects.h" |
45 #include "snapshot.h" | 43 #include "snapshot.h" |
(...skipping 12212 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
12258 v8::HandleScope outer(isolate); | 12256 v8::HandleScope outer(isolate); |
12259 v8::Local<Context> env = Context::New(isolate); | 12257 v8::Local<Context> env = Context::New(isolate); |
12260 env->Enter(); | 12258 env->Enter(); |
12261 v8::Handle<Value> value = NestedScope(env); | 12259 v8::Handle<Value> value = NestedScope(env); |
12262 v8::Handle<String> str(value->ToString()); | 12260 v8::Handle<String> str(value->ToString()); |
12263 CHECK(!str.IsEmpty()); | 12261 CHECK(!str.IsEmpty()); |
12264 env->Exit(); | 12262 env->Exit(); |
12265 } | 12263 } |
12266 | 12264 |
12267 | 12265 |
12268 static bool MatchPointers(void* key1, void* key2) { | 12266 static i::Handle<i::JSFunction>* foo_ptr = NULL; |
12269 return key1 == key2; | 12267 static int foo_entry_count = 0; |
12270 } | 12268 static i::Handle<i::JSFunction>* bar_ptr = NULL; |
| 12269 static int bar_entry_count = 0; |
| 12270 static int bar_caller_count = 0; |
12271 | 12271 |
12272 | 12272 |
12273 struct SymbolInfo { | 12273 static void entry_hook(uintptr_t function, |
12274 size_t id; | 12274 uintptr_t return_addr_location) { |
12275 size_t size; | 12275 i::Code* code = i::Code::GetCodeFromTargetAddress( |
12276 std::string name; | 12276 reinterpret_cast<i::Address>(function)); |
12277 }; | 12277 CHECK(code != NULL); |
12278 | 12278 |
| 12279 if (bar_ptr != NULL && code == (*bar_ptr)->code()) |
| 12280 ++bar_entry_count; |
12279 | 12281 |
12280 class SetFunctionEntryHookTest { | 12282 if (foo_ptr != NULL && code == (*foo_ptr)->code()) |
12281 public: | 12283 ++foo_entry_count; |
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 | 12284 |
12302 void OnEntryHook(uintptr_t function, | 12285 // Let's check whether bar is the caller. |
12303 uintptr_t return_addr_location); | 12286 if (bar_ptr != NULL) { |
12304 static void EntryHook(uintptr_t function, | 12287 const v8::internal::byte* caller = |
12305 uintptr_t return_addr_location) { | 12288 *reinterpret_cast<v8::internal::byte**>(return_addr_location); |
12306 CHECK(instance_ != NULL); | |
12307 instance_->OnEntryHook(function, return_addr_location); | |
12308 } | |
12309 | 12289 |
12310 static void RuntimeCallback(const v8::FunctionCallbackInfo<v8::Value>& args) { | 12290 if ((*bar_ptr)->code()->instruction_start() <= caller && |
12311 CHECK(instance_ != NULL); | 12291 (*bar_ptr)->code()->instruction_end() > caller) { |
12312 args.GetReturnValue().Set(v8_num(42)); | 12292 ++bar_caller_count; |
12313 } | 12293 } |
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 size_t 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*>, size_t> 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 } | 12294 } |
12373 } | 12295 } |
12374 | 12296 |
12375 | 12297 |
12376 void SetFunctionEntryHookTest::OnJitEvent(const v8::JitCodeEvent* event) { | 12298 static void RunLoopInNewEnv() { |
12377 switch (event->type) { | 12299 bar_ptr = NULL; |
12378 case v8::JitCodeEvent::CODE_ADDED: { | 12300 foo_ptr = NULL; |
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 | 12301 |
12384 // Record the new symbol. | 12302 v8::Isolate* isolate = v8::Isolate::GetCurrent(); |
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( | |
12423 reinterpret_cast<i::Address>(function)); | |
12424 CHECK(function_code != NULL); | |
12425 | |
12426 // Then try and look up the caller's code object. | |
12427 i::Address caller = *reinterpret_cast<i::Address*>(return_addr_location); | |
12428 | |
12429 // Count the invocation. | |
12430 SymbolInfo* caller_symbol = FindSymbolForAddr(caller); | |
12431 SymbolInfo* function_symbol = | |
12432 FindSymbolForAddr(reinterpret_cast<i::Address>(function)); | |
12433 ++invocations_[std::make_pair(caller_symbol, function_symbol)]; | |
12434 | |
12435 if (!bar_func_.is_null() && function_code == bar_func_->code()) { | |
12436 // Check that we have a symbol for the "bar" function at the right location. | |
12437 SymbolLocationMap::iterator it( | |
12438 symbol_locations_.find(function_code->instruction_start())); | |
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 size_t SetFunctionEntryHookTest::CountInvocations( | |
12473 const char* caller_name, const char* function_name) { | |
12474 InvocationMap::iterator it(invocations_.begin()); | |
12475 size_t 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; | |
12484 } | |
12485 | |
12486 // Filter out non-matching callers. | |
12487 if (caller_name != NULL) { | |
12488 if (caller == NULL) | |
12489 continue; | |
12490 if (caller->name.find(caller_name) == std::string::npos) | |
12491 continue; | |
12492 } | |
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) { | |
12503 v8::HandleScope outer(isolate); | 12303 v8::HandleScope outer(isolate); |
12504 v8::Local<Context> env = Context::New(isolate); | 12304 v8::Local<Context> env = Context::New(isolate); |
12505 env->Enter(); | 12305 env->Enter(); |
12506 | 12306 |
12507 Local<ObjectTemplate> t = ObjectTemplate::New(); | 12307 const char* script = |
12508 t->Set(v8_str("asdf"), v8::FunctionTemplate::New(RuntimeCallback)); | 12308 "function bar() {" |
12509 env->Global()->Set(v8_str("obj"), t->NewInstance()); | 12309 " var sum = 0;" |
| 12310 " for (i = 0; i < 100; ++i)" |
| 12311 " sum = foo(i);" |
| 12312 " return sum;" |
| 12313 "}" |
| 12314 "function foo(i) { return i * i; }"; |
| 12315 CompileRun(script); |
| 12316 i::Handle<i::JSFunction> bar = |
| 12317 i::Handle<i::JSFunction>::cast( |
| 12318 v8::Utils::OpenHandle(*env->Global()->Get(v8_str("bar")))); |
| 12319 ASSERT(*bar); |
12510 | 12320 |
12511 const char* script = | 12321 i::Handle<i::JSFunction> foo = |
12512 "function bar() {\n" | |
12513 " var sum = 0;\n" | |
12514 " for (i = 0; i < 100; ++i)\n" | |
12515 " sum = foo(i);\n" | |
12516 " return sum;\n" | |
12517 "}\n" | |
12518 "function foo(i) { return i * i; }\n" | |
12519 "// Invoke on the runtime function.\n" | |
12520 "obj.asdf()"; | |
12521 CompileRun(script); | |
12522 bar_func_ = i::Handle<i::JSFunction>::cast( | |
12523 v8::Utils::OpenHandle(*env->Global()->Get(v8_str("bar")))); | |
12524 ASSERT(!bar_func_.is_null()); | |
12525 | |
12526 foo_func_ = | |
12527 i::Handle<i::JSFunction>::cast( | 12322 i::Handle<i::JSFunction>::cast( |
12528 v8::Utils::OpenHandle(*env->Global()->Get(v8_str("foo")))); | 12323 v8::Utils::OpenHandle(*env->Global()->Get(v8_str("foo")))); |
12529 ASSERT(!foo_func_.is_null()); | 12324 ASSERT(*foo); |
| 12325 |
| 12326 bar_ptr = &bar; |
| 12327 foo_ptr = &foo; |
12530 | 12328 |
12531 v8::Handle<v8::Value> value = CompileRun("bar();"); | 12329 v8::Handle<v8::Value> value = CompileRun("bar();"); |
12532 CHECK(value->IsNumber()); | 12330 CHECK(value->IsNumber()); |
12533 CHECK_EQ(9801.0, v8::Number::Cast(*value)->Value()); | 12331 CHECK_EQ(9801.0, v8::Number::Cast(*value)->Value()); |
12534 | 12332 |
12535 // Test the optimized codegen path. | 12333 // Test the optimized codegen path. |
12536 value = CompileRun("%OptimizeFunctionOnNextCall(foo);" | 12334 value = CompileRun("%OptimizeFunctionOnNextCall(foo);" |
12537 "bar();"); | 12335 "bar();"); |
12538 CHECK(value->IsNumber()); | 12336 CHECK(value->IsNumber()); |
12539 CHECK_EQ(9801.0, v8::Number::Cast(*value)->Value()); | 12337 CHECK_EQ(9801.0, v8::Number::Cast(*value)->Value()); |
12540 | 12338 |
12541 env->Exit(); | 12339 env->Exit(); |
12542 } | 12340 } |
12543 | 12341 |
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, 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 | |
12593 | 12342 |
12594 TEST(SetFunctionEntryHook) { | 12343 TEST(SetFunctionEntryHook) { |
12595 // FunctionEntryHook does not work well with experimental natives. | 12344 // FunctionEntryHook does not work well with experimental natives. |
12596 // Experimental natives are compiled during snapshot deserialization. | 12345 // Experimental natives are compiled during snapshot deserialization. |
12597 // This test breaks because InstallGetter (function from snapshot that | 12346 // This test breaks because InstallGetter (function from snapshot that |
12598 // only gets called from experimental natives) is compiled with entry hooks. | 12347 // only gets called from experimental natives) is compiled with entry hooks. |
12599 i::FLAG_harmony_typed_arrays = false; | 12348 i::FLAG_harmony_typed_arrays = false; |
12600 i::FLAG_harmony_array_buffer = false; | 12349 i::FLAG_harmony_array_buffer = false; |
12601 | 12350 |
12602 i::FLAG_allow_natives_syntax = true; | 12351 i::FLAG_allow_natives_syntax = true; |
12603 i::FLAG_use_inlining = false; | 12352 i::FLAG_use_inlining = false; |
12604 | 12353 |
12605 SetFunctionEntryHookTest test; | 12354 // Test setting and resetting the entry hook. |
12606 test.RunTest(); | 12355 // Nulling it should always succeed. |
| 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); |
12607 } | 12390 } |
12608 | 12391 |
12609 | 12392 |
12610 static i::HashMap* code_map = NULL; | 12393 static i::HashMap* code_map = NULL; |
12611 static i::HashMap* jitcode_line_info = NULL; | 12394 static i::HashMap* jitcode_line_info = NULL; |
12612 static int saw_bar = 0; | 12395 static int saw_bar = 0; |
12613 static int move_events = 0; | 12396 static int move_events = 0; |
12614 | 12397 |
12615 | 12398 |
12616 static bool FunctionNameIs(const char* expected, | 12399 static bool FunctionNameIs(const char* expected, |
(...skipping 121 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
12738 break; | 12521 break; |
12739 | 12522 |
12740 default: | 12523 default: |
12741 // Impossible event. | 12524 // Impossible event. |
12742 CHECK(false); | 12525 CHECK(false); |
12743 break; | 12526 break; |
12744 } | 12527 } |
12745 } | 12528 } |
12746 | 12529 |
12747 | 12530 |
| 12531 static bool MatchPointers(void* key1, void* key2) { |
| 12532 return key1 == key2; |
| 12533 } |
| 12534 |
| 12535 |
12748 TEST(SetJitCodeEventHandler) { | 12536 TEST(SetJitCodeEventHandler) { |
12749 i::FLAG_stress_compaction = true; | 12537 i::FLAG_stress_compaction = true; |
12750 i::FLAG_incremental_marking = false; | 12538 i::FLAG_incremental_marking = false; |
12751 const char* script = | 12539 const char* script = |
12752 "function bar() {" | 12540 "function bar() {" |
12753 " var sum = 0;" | 12541 " var sum = 0;" |
12754 " for (i = 0; i < 100; ++i)" | 12542 " for (i = 0; i < 100; ++i)" |
12755 " sum = foo(i);" | 12543 " sum = foo(i);" |
12756 " return sum;" | 12544 " return sum;" |
12757 "}" | 12545 "}" |
(...skipping 6802 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
19560 i::Semaphore* sem_; | 19348 i::Semaphore* sem_; |
19561 volatile int sem_value_; | 19349 volatile int sem_value_; |
19562 }; | 19350 }; |
19563 | 19351 |
19564 | 19352 |
19565 THREADED_TEST(SemaphoreInterruption) { | 19353 THREADED_TEST(SemaphoreInterruption) { |
19566 ThreadInterruptTest().RunTest(); | 19354 ThreadInterruptTest().RunTest(); |
19567 } | 19355 } |
19568 | 19356 |
19569 #endif // WIN32 | 19357 #endif // WIN32 |
OLD | NEW |