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

Side by Side Diff: src/x64/stub-cache-x64.cc

Issue 148333003: crankshaft support for api method calls (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: fix Created 6 years, 10 months 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 | Annotate | Revision Log
« no previous file with comments | « src/x64/code-stubs-x64.cc ('k') | test/cctest/test-api.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 419 matching lines...) Expand 10 before | Expand all | Expand 10 after
430 Address function_address = v8::ToCData<Address>(api_call_info->callback()); 430 Address function_address = v8::ToCData<Address>(api_call_info->callback());
431 __ Move( 431 __ Move(
432 api_function_address, function_address, RelocInfo::EXTERNAL_REFERENCE); 432 api_function_address, function_address, RelocInfo::EXTERNAL_REFERENCE);
433 433
434 // Jump to stub. 434 // Jump to stub.
435 CallApiFunctionStub stub(restore_context, call_data_undefined, argc); 435 CallApiFunctionStub stub(restore_context, call_data_undefined, argc);
436 __ TailCallStub(&stub); 436 __ TailCallStub(&stub);
437 } 437 }
438 438
439 439
440 // Generates call to API function.
441 static void GenerateFastApiCall(MacroAssembler* masm,
442 const CallOptimization& optimization,
443 int argc,
444 Handle<Map> map_to_holder,
445 CallOptimization::HolderLookup holder_lookup) {
446 Counters* counters = masm->isolate()->counters();
447 __ IncrementCounter(counters->call_const_fast_api(), 1);
448
449 // Move holder to a register
450 Register holder_reg = rax;
451 switch (holder_lookup) {
452 case CallOptimization::kHolderIsReceiver:
453 {
454 ASSERT(map_to_holder.is_null());
455 StackArgumentsAccessor args(rsp, argc);
456 __ movp(holder_reg, args.GetReceiverOperand());
457 }
458 break;
459 case CallOptimization::kHolderIsPrototypeOfMap:
460 {
461 Handle<JSObject> holder(JSObject::cast(map_to_holder->prototype()));
462 if (!masm->isolate()->heap()->InNewSpace(*holder)) {
463 __ Move(holder_reg, holder);
464 } else {
465 __ Move(holder_reg, map_to_holder);
466 __ movp(holder_reg, FieldOperand(holder_reg, Map::kPrototypeOffset));
467 }
468 }
469 break;
470 case CallOptimization::kHolderNotFound:
471 UNREACHABLE();
472 }
473 GenerateFastApiCallBody(masm,
474 optimization,
475 argc,
476 holder_reg,
477 false);
478 }
479
480
481 // Generate call to api function. 440 // Generate call to api function.
482 static void GenerateFastApiCall(MacroAssembler* masm, 441 static void GenerateFastApiCall(MacroAssembler* masm,
483 const CallOptimization& optimization, 442 const CallOptimization& optimization,
484 Register receiver, 443 Register receiver,
485 Register scratch1, 444 Register scratch1,
486 int argc, 445 int argc,
487 Register* values) { 446 Register* values) {
488 __ PopReturnAddressTo(scratch1); 447 __ PopReturnAddressTo(scratch1);
489 // receiver 448 // receiver
490 __ push(receiver); 449 __ push(receiver);
(...skipping 87 matching lines...) Expand 10 before | Expand all | Expand 10 after
578 537
579 // Check that the maps from interceptor's holder to constant function's 538 // Check that the maps from interceptor's holder to constant function's
580 // holder haven't changed and thus we can use cached constant function. 539 // holder haven't changed and thus we can use cached constant function.
581 if (*interceptor_holder != lookup->holder()) { 540 if (*interceptor_holder != lookup->holder()) {
582 stub_compiler_->CheckPrototypes( 541 stub_compiler_->CheckPrototypes(
583 IC::CurrentTypeOf(interceptor_holder, masm->isolate()), holder, 542 IC::CurrentTypeOf(interceptor_holder, masm->isolate()), holder,
584 handle(lookup->holder()), scratch1, scratch2, scratch3, 543 handle(lookup->holder()), scratch1, scratch2, scratch3,
585 name, miss_label); 544 name, miss_label);
586 } 545 }
587 546
588 Handle<Map> lookup_map; 547 Handle<JSFunction> fun = optimization.constant_function();
589 CallOptimization::HolderLookup holder_lookup = 548 stub_compiler_->GenerateJumpFunction(object, fun);
590 CallOptimization::kHolderNotFound;
591 if (optimization.is_simple_api_call() &&
592 !lookup->holder()->IsGlobalObject()) {
593 lookup_map = optimization.LookupHolderOfExpectedType(
594 object, object, interceptor_holder, &holder_lookup);
595 if (holder_lookup == CallOptimization::kHolderNotFound) {
596 lookup_map =
597 optimization.LookupHolderOfExpectedType(
598 object,
599 interceptor_holder,
600 Handle<JSObject>(lookup->holder()),
601 &holder_lookup);
602 }
603 }
604
605 // Invoke function.
606 if (holder_lookup != CallOptimization::kHolderNotFound) {
607 int argc = arguments_.immediate();
608 GenerateFastApiCall(masm,
609 optimization,
610 argc,
611 lookup_map,
612 holder_lookup);
613 } else {
614 Handle<JSFunction> fun = optimization.constant_function();
615 stub_compiler_->GenerateJumpFunction(object, fun);
616 }
617 549
618 // Invoke a regular function. 550 // Invoke a regular function.
619 __ bind(&regular_invoke); 551 __ bind(&regular_invoke);
620 } 552 }
621 553
622 void CompileRegular(MacroAssembler* masm, 554 void CompileRegular(MacroAssembler* masm,
623 Handle<JSObject> object, 555 Handle<JSObject> object,
624 Register receiver, 556 Register receiver,
625 Register scratch1, 557 Register scratch1,
626 Register scratch2, 558 Register scratch2,
(...skipping 767 matching lines...) Expand 10 before | Expand all | Expand 10 after
1394 index.translate(holder), Representation::Tagged()); 1326 index.translate(holder), Representation::Tagged());
1395 GenerateJumpFunction(object, rdi, &miss); 1327 GenerateJumpFunction(object, rdi, &miss);
1396 1328
1397 HandlerFrontendFooter(&miss); 1329 HandlerFrontendFooter(&miss);
1398 1330
1399 // Return the generated code. 1331 // Return the generated code.
1400 return GetCode(Code::FAST, name); 1332 return GetCode(Code::FAST, name);
1401 } 1333 }
1402 1334
1403 1335
1404 Handle<Code> CallStubCompiler::CompileFastApiCall(
1405 const CallOptimization& optimization,
1406 Handle<Object> object,
1407 Handle<JSObject> holder,
1408 Handle<Cell> cell,
1409 Handle<JSFunction> function,
1410 Handle<String> name) {
1411 ASSERT(optimization.is_simple_api_call());
1412 // Bail out if object is a global object as we don't want to
1413 // repatch it to global receiver.
1414 if (object->IsGlobalObject()) return Handle<Code>::null();
1415 if (!cell.is_null()) return Handle<Code>::null();
1416 if (!object->IsJSObject()) return Handle<Code>::null();
1417 Handle<JSObject> receiver = Handle<JSObject>::cast(object);
1418 CallOptimization::HolderLookup holder_lookup =
1419 CallOptimization::kHolderNotFound;
1420 Handle<Map> lookup_map = optimization.LookupHolderOfExpectedType(
1421 receiver, receiver, holder, &holder_lookup);
1422 if (holder_lookup == CallOptimization::kHolderNotFound) {
1423 return Handle<Code>::null();
1424 }
1425
1426 Label miss;
1427 GenerateNameCheck(name, &miss);
1428
1429 const int argc = arguments().immediate();
1430 StackArgumentsAccessor args(rsp, argc);
1431 __ movp(rdx, args.GetReceiverOperand());
1432
1433 // Check that the receiver isn't a smi.
1434 __ JumpIfSmi(rdx, &miss);
1435
1436 Counters* counters = isolate()->counters();
1437 __ IncrementCounter(counters->call_const(), 1);
1438
1439 // Check that the maps haven't changed and find a Holder as a side effect.
1440 CheckPrototypes(IC::CurrentTypeOf(object, isolate()), rdx, holder,
1441 rbx, rax, rdi, name, &miss);
1442
1443 GenerateFastApiCall(masm(), optimization, argc, lookup_map, holder_lookup);
1444
1445 HandlerFrontendFooter(&miss);
1446
1447 // Return the generated code.
1448 return GetCode(function);
1449 }
1450
1451
1452 void StubCompiler::GenerateBooleanCheck(Register object, Label* miss) { 1336 void StubCompiler::GenerateBooleanCheck(Register object, Label* miss) {
1453 Label success; 1337 Label success;
1454 // Check that the object is a boolean. 1338 // Check that the object is a boolean.
1455 __ CompareRoot(object, Heap::kTrueValueRootIndex); 1339 __ CompareRoot(object, Heap::kTrueValueRootIndex);
1456 __ j(equal, &success); 1340 __ j(equal, &success);
1457 __ CompareRoot(object, Heap::kFalseValueRootIndex); 1341 __ CompareRoot(object, Heap::kFalseValueRootIndex);
1458 __ j(not_equal, miss); 1342 __ j(not_equal, miss);
1459 __ bind(&success); 1343 __ bind(&success);
1460 } 1344 }
1461 1345
(...skipping 130 matching lines...) Expand 10 before | Expand all | Expand 10 after
1592 return GetCode(Code::FAST, name); 1476 return GetCode(Code::FAST, name);
1593 } 1477 }
1594 1478
1595 1479
1596 Handle<Code> CallStubCompiler::CompileCallGlobal( 1480 Handle<Code> CallStubCompiler::CompileCallGlobal(
1597 Handle<JSObject> object, 1481 Handle<JSObject> object,
1598 Handle<GlobalObject> holder, 1482 Handle<GlobalObject> holder,
1599 Handle<PropertyCell> cell, 1483 Handle<PropertyCell> cell,
1600 Handle<JSFunction> function, 1484 Handle<JSFunction> function,
1601 Handle<Name> name) { 1485 Handle<Name> name) {
1602 if (HasCustomCallGenerator(function)) {
1603 Handle<Code> code = CompileCustomCall(
1604 object, holder, cell, function, Handle<String>::cast(name),
1605 Code::NORMAL);
1606 // A null handle means bail out to the regular compiler code below.
1607 if (!code.is_null()) return code;
1608 }
1609
1610 Label miss; 1486 Label miss;
1611 HandlerFrontendHeader(object, holder, name, RECEIVER_MAP_CHECK, &miss); 1487 HandlerFrontendHeader(object, holder, name, RECEIVER_MAP_CHECK, &miss);
1612 // Potentially loads a closure that matches the shared function info of the 1488 // Potentially loads a closure that matches the shared function info of the
1613 // function, rather than function. 1489 // function, rather than function.
1614 GenerateLoadFunctionFromCell(cell, function, &miss); 1490 GenerateLoadFunctionFromCell(cell, function, &miss);
1615 Counters* counters = isolate()->counters(); 1491 Counters* counters = isolate()->counters();
1616 __ IncrementCounter(counters->call_global_inline(), 1); 1492 __ IncrementCounter(counters->call_global_inline(), 1);
1617 GenerateJumpFunction(object, rdi, function); 1493 GenerateJumpFunction(object, rdi, function);
1618 HandlerFrontendFooter(&miss); 1494 HandlerFrontendFooter(&miss);
1619 1495
(...skipping 358 matching lines...) Expand 10 before | Expand all | Expand 10 after
1978 // ----------------------------------- 1854 // -----------------------------------
1979 TailCallBuiltin(masm, Builtins::kKeyedLoadIC_Miss); 1855 TailCallBuiltin(masm, Builtins::kKeyedLoadIC_Miss);
1980 } 1856 }
1981 1857
1982 1858
1983 #undef __ 1859 #undef __
1984 1860
1985 } } // namespace v8::internal 1861 } } // namespace v8::internal
1986 1862
1987 #endif // V8_TARGET_ARCH_X64 1863 #endif // V8_TARGET_ARCH_X64
OLDNEW
« no previous file with comments | « src/x64/code-stubs-x64.cc ('k') | test/cctest/test-api.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698