Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(96)

Side by Side Diff: test/cctest/test-compiler.cc

Issue 1423723002: Map v8::Function to JSReceiver + IsCallable (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: updates Created 5 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « test/cctest/test-api.cc ('k') | test/cctest/test-cpu-profiler.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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 280 matching lines...) Expand 10 before | Expand all | Expand 10 after
291 i::FLAG_allow_natives_syntax = true; 291 i::FLAG_allow_natives_syntax = true;
292 CcTest::InitializeVM(); 292 CcTest::InitializeVM();
293 if (!CcTest::i_isolate()->use_crankshaft()) return; 293 if (!CcTest::i_isolate()->use_crankshaft()) return;
294 v8::HandleScope scope(CcTest::isolate()); 294 v8::HandleScope scope(CcTest::isolate());
295 295
296 // Make sure function f has a call that uses a type feedback slot. 296 // Make sure function f has a call that uses a type feedback slot.
297 CompileRun("function fun() {};" 297 CompileRun("function fun() {};"
298 "fun1 = fun;" 298 "fun1 = fun;"
299 "function f(a) { a(); } f(fun1);"); 299 "function f(a) { a(); } f(fun1);");
300 300
301 Handle<JSFunction> f = 301 Handle<JSFunction> f = Handle<JSFunction>::cast(v8::Utils::OpenHandle(
302 v8::Utils::OpenHandle( 302 *v8::Handle<v8::Function>::Cast(CcTest::global()->Get(v8_str("f")))));
303 *v8::Handle<v8::Function>::Cast(
304 CcTest::global()->Get(v8_str("f"))));
305 303
306 // We shouldn't have deoptimization support. We want to recompile and 304 // We shouldn't have deoptimization support. We want to recompile and
307 // verify that our feedback vector preserves information. 305 // verify that our feedback vector preserves information.
308 CHECK(!f->shared()->has_deoptimization_support()); 306 CHECK(!f->shared()->has_deoptimization_support());
309 Handle<TypeFeedbackVector> feedback_vector(f->shared()->feedback_vector()); 307 Handle<TypeFeedbackVector> feedback_vector(f->shared()->feedback_vector());
310 308
311 // Verify that we gathered feedback. 309 // Verify that we gathered feedback.
312 CHECK(!feedback_vector->is_empty()); 310 CHECK(!feedback_vector->is_empty());
313 FeedbackVectorSlot slot_for_a(0); 311 FeedbackVectorSlot slot_for_a(0);
314 Object* object = feedback_vector->Get(slot_for_a); 312 Object* object = feedback_vector->Get(slot_for_a);
(...skipping 22 matching lines...) Expand all
337 " return (function() {" 335 " return (function() {"
338 " eval('');" 336 " eval('');"
339 " return function() {" 337 " return function() {"
340 " 'use strict';" 338 " 'use strict';"
341 " call_target();" 339 " call_target();"
342 " }" 340 " }"
343 " })();" 341 " })();"
344 "}" 342 "}"
345 "morphing_call = builder();"); 343 "morphing_call = builder();");
346 344
347 Handle<JSFunction> f = 345 Handle<JSFunction> f = Handle<JSFunction>::cast(
348 v8::Utils::OpenHandle( 346 v8::Utils::OpenHandle(*v8::Handle<v8::Function>::Cast(
349 *v8::Handle<v8::Function>::Cast( 347 CcTest::global()->Get(v8_str("morphing_call")))));
350 CcTest::global()->Get(v8_str("morphing_call"))));
351 348
352 // Not compiled, and so no feedback vector allocated yet. 349 // Not compiled, and so no feedback vector allocated yet.
353 CHECK(!f->shared()->is_compiled()); 350 CHECK(!f->shared()->is_compiled());
354 CHECK(f->shared()->feedback_vector()->is_empty()); 351 CHECK(f->shared()->feedback_vector()->is_empty());
355 352
356 CompileRun("morphing_call();"); 353 CompileRun("morphing_call();");
357 354
358 // Now a feedback vector is allocated. 355 // Now a feedback vector is allocated.
359 CHECK(f->shared()->is_compiled()); 356 CHECK(f->shared()->is_compiled());
360 CHECK(!f->shared()->feedback_vector()->is_empty()); 357 CHECK(!f->shared()->feedback_vector()->is_empty());
(...skipping 14 matching lines...) Expand all
375 CompileRun( 372 CompileRun(
376 "function MakeClosure() {" 373 "function MakeClosure() {"
377 " return function() { return x; };" 374 " return function() { return x; };"
378 "}" 375 "}"
379 "var closure0 = MakeClosure();" 376 "var closure0 = MakeClosure();"
380 "%DebugPrint(closure0());" 377 "%DebugPrint(closure0());"
381 "%OptimizeFunctionOnNextCall(closure0);" 378 "%OptimizeFunctionOnNextCall(closure0);"
382 "%DebugPrint(closure0());" 379 "%DebugPrint(closure0());"
383 "var closure1 = MakeClosure();" 380 "var closure1 = MakeClosure();"
384 "var closure2 = MakeClosure();"); 381 "var closure2 = MakeClosure();");
385 Handle<JSFunction> fun1 = v8::Utils::OpenHandle( 382 Handle<JSFunction> fun1 = Handle<JSFunction>::cast(
386 *v8::Local<v8::Function>::Cast(env->Global()->Get(v8_str("closure1")))); 383 v8::Utils::OpenHandle(*v8::Local<v8::Function>::Cast(
387 Handle<JSFunction> fun2 = v8::Utils::OpenHandle( 384 env->Global()->Get(v8_str("closure1")))));
388 *v8::Local<v8::Function>::Cast(env->Global()->Get(v8_str("closure2")))); 385 Handle<JSFunction> fun2 = Handle<JSFunction>::cast(
386 v8::Utils::OpenHandle(*v8::Local<v8::Function>::Cast(
387 env->Global()->Get(v8_str("closure2")))));
389 CHECK(fun1->IsOptimized() || !CcTest::i_isolate()->use_crankshaft()); 388 CHECK(fun1->IsOptimized() || !CcTest::i_isolate()->use_crankshaft());
390 CHECK(fun2->IsOptimized() || !CcTest::i_isolate()->use_crankshaft()); 389 CHECK(fun2->IsOptimized() || !CcTest::i_isolate()->use_crankshaft());
391 CHECK_EQ(fun1->code(), fun2->code()); 390 CHECK_EQ(fun1->code(), fun2->code());
392 } 391 }
393 } 392 }
394 393
395 394
396 // Test that optimized code for different closures is actually shared 395 // Test that optimized code for different closures is actually shared
397 // immediately by the FastNewClosureStub when run different contexts. 396 // immediately by the FastNewClosureStub when run different contexts.
398 TEST(OptimizedCodeSharing2) { 397 TEST(OptimizedCodeSharing2) {
(...skipping 13 matching lines...) Expand all
412 { 411 {
413 LocalContext env; 412 LocalContext env;
414 env->Global()->Set(v8::String::NewFromUtf8(CcTest::isolate(), "x"), 413 env->Global()->Set(v8::String::NewFromUtf8(CcTest::isolate(), "x"),
415 v8::Integer::New(CcTest::isolate(), 23)); 414 v8::Integer::New(CcTest::isolate(), 23));
416 script->GetUnboundScript()->BindToCurrentContext()->Run(); 415 script->GetUnboundScript()->BindToCurrentContext()->Run();
417 CompileRun( 416 CompileRun(
418 "var closure0 = MakeClosure();" 417 "var closure0 = MakeClosure();"
419 "%DebugPrint(closure0());" 418 "%DebugPrint(closure0());"
420 "%OptimizeFunctionOnNextCall(closure0);" 419 "%OptimizeFunctionOnNextCall(closure0);"
421 "%DebugPrint(closure0());"); 420 "%DebugPrint(closure0());");
422 Handle<JSFunction> fun0 = v8::Utils::OpenHandle( 421 Handle<JSFunction> fun0 = Handle<JSFunction>::cast(
423 *v8::Local<v8::Function>::Cast(env->Global()->Get(v8_str("closure0")))); 422 v8::Utils::OpenHandle(*v8::Local<v8::Function>::Cast(
423 env->Global()->Get(v8_str("closure0")))));
424 CHECK(fun0->IsOptimized() || !CcTest::i_isolate()->use_crankshaft()); 424 CHECK(fun0->IsOptimized() || !CcTest::i_isolate()->use_crankshaft());
425 reference_code = handle(fun0->code()); 425 reference_code = handle(fun0->code());
426 } 426 }
427 for (int i = 0; i < 3; i++) { 427 for (int i = 0; i < 3; i++) {
428 LocalContext env; 428 LocalContext env;
429 env->Global()->Set(v8::String::NewFromUtf8(CcTest::isolate(), "x"), 429 env->Global()->Set(v8::String::NewFromUtf8(CcTest::isolate(), "x"),
430 v8::Integer::New(CcTest::isolate(), i)); 430 v8::Integer::New(CcTest::isolate(), i));
431 script->GetUnboundScript()->BindToCurrentContext()->Run(); 431 script->GetUnboundScript()->BindToCurrentContext()->Run();
432 CompileRun( 432 CompileRun(
433 "var closure0 = MakeClosure();" 433 "var closure0 = MakeClosure();"
434 "%DebugPrint(closure0());" 434 "%DebugPrint(closure0());"
435 "%OptimizeFunctionOnNextCall(closure0);" 435 "%OptimizeFunctionOnNextCall(closure0);"
436 "%DebugPrint(closure0());" 436 "%DebugPrint(closure0());"
437 "var closure1 = MakeClosure();" 437 "var closure1 = MakeClosure();"
438 "var closure2 = MakeClosure();"); 438 "var closure2 = MakeClosure();");
439 Handle<JSFunction> fun1 = v8::Utils::OpenHandle( 439 Handle<JSFunction> fun1 = Handle<JSFunction>::cast(
440 *v8::Local<v8::Function>::Cast(env->Global()->Get(v8_str("closure1")))); 440 v8::Utils::OpenHandle(*v8::Local<v8::Function>::Cast(
441 Handle<JSFunction> fun2 = v8::Utils::OpenHandle( 441 env->Global()->Get(v8_str("closure1")))));
442 *v8::Local<v8::Function>::Cast(env->Global()->Get(v8_str("closure2")))); 442 Handle<JSFunction> fun2 = Handle<JSFunction>::cast(
443 v8::Utils::OpenHandle(*v8::Local<v8::Function>::Cast(
444 env->Global()->Get(v8_str("closure2")))));
443 CHECK(fun1->IsOptimized() || !CcTest::i_isolate()->use_crankshaft()); 445 CHECK(fun1->IsOptimized() || !CcTest::i_isolate()->use_crankshaft());
444 CHECK(fun2->IsOptimized() || !CcTest::i_isolate()->use_crankshaft()); 446 CHECK(fun2->IsOptimized() || !CcTest::i_isolate()->use_crankshaft());
445 CHECK_EQ(*reference_code, fun1->code()); 447 CHECK_EQ(*reference_code, fun1->code());
446 CHECK_EQ(*reference_code, fun2->code()); 448 CHECK_EQ(*reference_code, fun2->code());
447 } 449 }
448 } 450 }
449 451
450 452
451 // Test that optimized code for different closures is actually shared 453 // Test that optimized code for different closures is actually shared
452 // immediately by the FastNewClosureStub without context-dependent entries. 454 // immediately by the FastNewClosureStub without context-dependent entries.
(...skipping 14 matching lines...) Expand all
467 { 469 {
468 LocalContext env; 470 LocalContext env;
469 env->Global()->Set(v8::String::NewFromUtf8(CcTest::isolate(), "x"), 471 env->Global()->Set(v8::String::NewFromUtf8(CcTest::isolate(), "x"),
470 v8::Integer::New(CcTest::isolate(), 23)); 472 v8::Integer::New(CcTest::isolate(), 23));
471 script->GetUnboundScript()->BindToCurrentContext()->Run(); 473 script->GetUnboundScript()->BindToCurrentContext()->Run();
472 CompileRun( 474 CompileRun(
473 "var closure0 = MakeClosure();" 475 "var closure0 = MakeClosure();"
474 "%DebugPrint(closure0());" 476 "%DebugPrint(closure0());"
475 "%OptimizeFunctionOnNextCall(closure0);" 477 "%OptimizeFunctionOnNextCall(closure0);"
476 "%DebugPrint(closure0());"); 478 "%DebugPrint(closure0());");
477 Handle<JSFunction> fun0 = v8::Utils::OpenHandle( 479 Handle<JSFunction> fun0 = Handle<JSFunction>::cast(
478 *v8::Local<v8::Function>::Cast(env->Global()->Get(v8_str("closure0")))); 480 v8::Utils::OpenHandle(*v8::Local<v8::Function>::Cast(
481 env->Global()->Get(v8_str("closure0")))));
479 CHECK(fun0->IsOptimized() || !CcTest::i_isolate()->use_crankshaft()); 482 CHECK(fun0->IsOptimized() || !CcTest::i_isolate()->use_crankshaft());
480 reference_code = handle(fun0->code()); 483 reference_code = handle(fun0->code());
481 // Evict only the context-dependent entry from the optimized code map. This 484 // Evict only the context-dependent entry from the optimized code map. This
482 // leaves it in a state where only the context-independent entry exists. 485 // leaves it in a state where only the context-independent entry exists.
483 fun0->shared()->TrimOptimizedCodeMap(SharedFunctionInfo::kEntryLength); 486 fun0->shared()->TrimOptimizedCodeMap(SharedFunctionInfo::kEntryLength);
484 } 487 }
485 for (int i = 0; i < 3; i++) { 488 for (int i = 0; i < 3; i++) {
486 LocalContext env; 489 LocalContext env;
487 env->Global()->Set(v8::String::NewFromUtf8(CcTest::isolate(), "x"), 490 env->Global()->Set(v8::String::NewFromUtf8(CcTest::isolate(), "x"),
488 v8::Integer::New(CcTest::isolate(), i)); 491 v8::Integer::New(CcTest::isolate(), i));
489 script->GetUnboundScript()->BindToCurrentContext()->Run(); 492 script->GetUnboundScript()->BindToCurrentContext()->Run();
490 CompileRun( 493 CompileRun(
491 "var closure0 = MakeClosure();" 494 "var closure0 = MakeClosure();"
492 "%DebugPrint(closure0());" 495 "%DebugPrint(closure0());"
493 "%OptimizeFunctionOnNextCall(closure0);" 496 "%OptimizeFunctionOnNextCall(closure0);"
494 "%DebugPrint(closure0());" 497 "%DebugPrint(closure0());"
495 "var closure1 = MakeClosure();" 498 "var closure1 = MakeClosure();"
496 "var closure2 = MakeClosure();"); 499 "var closure2 = MakeClosure();");
497 Handle<JSFunction> fun1 = v8::Utils::OpenHandle( 500 Handle<JSFunction> fun1 = Handle<JSFunction>::cast(
498 *v8::Local<v8::Function>::Cast(env->Global()->Get(v8_str("closure1")))); 501 v8::Utils::OpenHandle(*v8::Local<v8::Function>::Cast(
499 Handle<JSFunction> fun2 = v8::Utils::OpenHandle( 502 env->Global()->Get(v8_str("closure1")))));
500 *v8::Local<v8::Function>::Cast(env->Global()->Get(v8_str("closure2")))); 503 Handle<JSFunction> fun2 = Handle<JSFunction>::cast(
504 v8::Utils::OpenHandle(*v8::Local<v8::Function>::Cast(
505 env->Global()->Get(v8_str("closure2")))));
501 CHECK(fun1->IsOptimized() || !CcTest::i_isolate()->use_crankshaft()); 506 CHECK(fun1->IsOptimized() || !CcTest::i_isolate()->use_crankshaft());
502 CHECK(fun2->IsOptimized() || !CcTest::i_isolate()->use_crankshaft()); 507 CHECK(fun2->IsOptimized() || !CcTest::i_isolate()->use_crankshaft());
503 CHECK_EQ(*reference_code, fun1->code()); 508 CHECK_EQ(*reference_code, fun1->code());
504 CHECK_EQ(*reference_code, fun2->code()); 509 CHECK_EQ(*reference_code, fun2->code());
505 } 510 }
506 } 511 }
507 512
508 513
509 TEST(CompileFunctionInContext) { 514 TEST(CompileFunctionInContext) {
510 CcTest::InitializeVM(); 515 CcTest::InitializeVM();
(...skipping 126 matching lines...) Expand 10 before | Expand all | Expand 10 after
637 CHECK(!stack.IsEmpty()); 642 CHECK(!stack.IsEmpty());
638 CHECK(stack->GetFrameCount() > 0); 643 CHECK(stack->GetFrameCount() > 0);
639 v8::Local<v8::StackFrame> frame = stack->GetFrame(0); 644 v8::Local<v8::StackFrame> frame = stack->GetFrame(0);
640 CHECK_EQ(23, frame->GetLineNumber()); 645 CHECK_EQ(23, frame->GetLineNumber());
641 CHECK_EQ(42 + strlen("throw "), static_cast<unsigned>(frame->GetColumn())); 646 CHECK_EQ(42 + strlen("throw "), static_cast<unsigned>(frame->GetColumn()));
642 } 647 }
643 648
644 649
645 #ifdef ENABLE_DISASSEMBLER 650 #ifdef ENABLE_DISASSEMBLER
646 static Handle<JSFunction> GetJSFunction(v8::Handle<v8::Object> obj, 651 static Handle<JSFunction> GetJSFunction(v8::Handle<v8::Object> obj,
647 const char* property_name) { 652 const char* property_name) {
648 v8::Local<v8::Function> fun = 653 v8::Local<v8::Function> fun =
649 v8::Local<v8::Function>::Cast(obj->Get(v8_str(property_name))); 654 v8::Local<v8::Function>::Cast(obj->Get(v8_str(property_name)));
650 return v8::Utils::OpenHandle(*fun); 655 return Handle<JSFunction>::cast(v8::Utils::OpenHandle(*fun));
651 } 656 }
652 657
653 658
654 static void CheckCodeForUnsafeLiteral(Handle<JSFunction> f) { 659 static void CheckCodeForUnsafeLiteral(Handle<JSFunction> f) {
655 // Create a disassembler with default name lookup. 660 // Create a disassembler with default name lookup.
656 disasm::NameConverter name_converter; 661 disasm::NameConverter name_converter;
657 disasm::Disassembler d(name_converter); 662 disasm::Disassembler d(name_converter);
658 663
659 if (f->code()->kind() == Code::FUNCTION) { 664 if (f->code()->kind() == Code::FUNCTION) {
660 Address pc = f->code()->instruction_start(); 665 Address pc = f->code()->instruction_start();
(...skipping 29 matching lines...) Expand all
690 CompileRun("function f() { a = 12345678 }; f();"); 695 CompileRun("function f() { a = 12345678 }; f();");
691 CheckCodeForUnsafeLiteral(GetJSFunction(context->Global(), "f")); 696 CheckCodeForUnsafeLiteral(GetJSFunction(context->Global(), "f"));
692 CompileRun("function f(x) { a = 12345678 + x}; f(1);"); 697 CompileRun("function f(x) { a = 12345678 + x}; f(1);");
693 CheckCodeForUnsafeLiteral(GetJSFunction(context->Global(), "f")); 698 CheckCodeForUnsafeLiteral(GetJSFunction(context->Global(), "f"));
694 CompileRun("function f(x) { var arguments = 1; x += 12345678}; f(1);"); 699 CompileRun("function f(x) { var arguments = 1; x += 12345678}; f(1);");
695 CheckCodeForUnsafeLiteral(GetJSFunction(context->Global(), "f")); 700 CheckCodeForUnsafeLiteral(GetJSFunction(context->Global(), "f"));
696 CompileRun("function f(x) { var arguments = 1; x = 12345678}; f(1);"); 701 CompileRun("function f(x) { var arguments = 1; x = 12345678}; f(1);");
697 CheckCodeForUnsafeLiteral(GetJSFunction(context->Global(), "f")); 702 CheckCodeForUnsafeLiteral(GetJSFunction(context->Global(), "f"));
698 } 703 }
699 #endif 704 #endif
OLDNEW
« no previous file with comments | « test/cctest/test-api.cc ('k') | test/cctest/test-cpu-profiler.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698