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

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

Issue 110573004: Merge bleeding_edge 17696:18016. (Closed) Base URL: https://v8.googlecode.com/svn/branches/experimental/parser
Patch Set: Created 7 years 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
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 433 matching lines...) Expand 10 before | Expand all | Expand 10 after
444 // -- esp[kFastApiCallArguments * 4] : first fast api call extra argument. 444 // -- esp[kFastApiCallArguments * 4] : first fast api call extra argument.
445 // -- esp[kFastApiCallArguments * 4 + 4] : last argument in the internal 445 // -- esp[kFastApiCallArguments * 4 + 4] : last argument in the internal
446 // frame. 446 // frame.
447 // ----------------------------------- 447 // -----------------------------------
448 __ pop(scratch); 448 __ pop(scratch);
449 __ add(esp, Immediate(kPointerSize * kFastApiCallArguments)); 449 __ add(esp, Immediate(kPointerSize * kFastApiCallArguments));
450 __ push(scratch); 450 __ push(scratch);
451 } 451 }
452 452
453 453
454 static void GenerateFastApiCallBody(MacroAssembler* masm,
455 const CallOptimization& optimization,
456 int argc,
457 bool restore_context);
458
459
454 // Generates call to API function. 460 // Generates call to API function.
455 static void GenerateFastApiCall(MacroAssembler* masm, 461 static void GenerateFastApiCall(MacroAssembler* masm,
456 const CallOptimization& optimization, 462 const CallOptimization& optimization,
457 int argc, 463 int argc) {
458 bool restore_context) {
459 // ----------- S t a t e -------------
460 // -- esp[0] : return address
461 // -- esp[4] - esp[28] : FunctionCallbackInfo, incl.
462 // : object passing the type check
463 // (set by CheckPrototypes)
464 // -- esp[32] : last argument
465 // -- ...
466 // -- esp[(argc + 7) * 4] : first argument
467 // -- esp[(argc + 8) * 4] : receiver
468 // -----------------------------------
469
470 typedef FunctionCallbackArguments FCA; 464 typedef FunctionCallbackArguments FCA;
471 // Save calling context. 465 // Save calling context.
472 __ mov(Operand(esp, (1 + FCA::kContextSaveIndex) * kPointerSize), esi); 466 __ mov(Operand(esp, (1 + FCA::kContextSaveIndex) * kPointerSize), esi);
473 467
474 // Get the function and setup the context. 468 // Get the function and setup the context.
475 Handle<JSFunction> function = optimization.constant_function(); 469 Handle<JSFunction> function = optimization.constant_function();
476 __ LoadHeapObject(edi, function); 470 __ LoadHeapObject(edi, function);
477 __ mov(esi, FieldOperand(edi, JSFunction::kContextOffset)); 471 __ mov(esi, FieldOperand(edi, JSFunction::kContextOffset));
478 472
479 // Construct the FunctionCallbackInfo. 473 // Construct the FunctionCallbackInfo.
(...skipping 12 matching lines...) Expand all
492 Immediate(reinterpret_cast<int>(masm->isolate()))); 486 Immediate(reinterpret_cast<int>(masm->isolate())));
493 __ mov(Operand(esp, (1 + FCA::kReturnValueOffset) * kPointerSize), 487 __ mov(Operand(esp, (1 + FCA::kReturnValueOffset) * kPointerSize),
494 masm->isolate()->factory()->undefined_value()); 488 masm->isolate()->factory()->undefined_value());
495 __ mov(Operand(esp, (1 + FCA::kReturnValueDefaultValueIndex) * kPointerSize), 489 __ mov(Operand(esp, (1 + FCA::kReturnValueDefaultValueIndex) * kPointerSize),
496 masm->isolate()->factory()->undefined_value()); 490 masm->isolate()->factory()->undefined_value());
497 491
498 // Prepare arguments. 492 // Prepare arguments.
499 STATIC_ASSERT(kFastApiCallArguments == 7); 493 STATIC_ASSERT(kFastApiCallArguments == 7);
500 __ lea(eax, Operand(esp, 1 * kPointerSize)); 494 __ lea(eax, Operand(esp, 1 * kPointerSize));
501 495
496 GenerateFastApiCallBody(masm, optimization, argc, false);
497 }
498
499
500 // Generate call to api function.
501 // This function uses push() to generate smaller, faster code than
502 // the version above. It is an optimization that should will be removed
503 // when api call ICs are generated in hydrogen.
504 static void GenerateFastApiCall(MacroAssembler* masm,
505 const CallOptimization& optimization,
506 Register receiver,
507 Register scratch1,
508 Register scratch2,
509 Register scratch3,
510 int argc,
511 Register* values) {
512 ASSERT(optimization.is_simple_api_call());
513
514 // Copy return value.
515 __ pop(scratch1);
516
517 // receiver
518 __ push(receiver);
519
520 // Write the arguments to stack frame.
521 for (int i = 0; i < argc; i++) {
522 Register arg = values[argc-1-i];
523 ASSERT(!receiver.is(arg));
524 ASSERT(!scratch1.is(arg));
525 ASSERT(!scratch2.is(arg));
526 ASSERT(!scratch3.is(arg));
527 __ push(arg);
528 }
529
530 typedef FunctionCallbackArguments FCA;
531
532 STATIC_ASSERT(FCA::kHolderIndex == 0);
533 STATIC_ASSERT(FCA::kIsolateIndex == 1);
534 STATIC_ASSERT(FCA::kReturnValueDefaultValueIndex == 2);
535 STATIC_ASSERT(FCA::kReturnValueOffset == 3);
536 STATIC_ASSERT(FCA::kDataIndex == 4);
537 STATIC_ASSERT(FCA::kCalleeIndex == 5);
538 STATIC_ASSERT(FCA::kContextSaveIndex == 6);
539 STATIC_ASSERT(FCA::kArgsLength == 7);
540
541 // context save
542 __ push(esi);
543
544 // Get the function and setup the context.
545 Handle<JSFunction> function = optimization.constant_function();
546 __ LoadHeapObject(scratch2, function);
547 __ mov(esi, FieldOperand(scratch2, JSFunction::kContextOffset));
548 // callee
549 __ push(scratch2);
550
551 Isolate* isolate = masm->isolate();
552 Handle<CallHandlerInfo> api_call_info = optimization.api_call_info();
553 Handle<Object> call_data(api_call_info->data(), isolate);
554 // Push data from ExecutableAccessorInfo.
555 if (isolate->heap()->InNewSpace(*call_data)) {
556 __ mov(scratch2, api_call_info);
557 __ mov(scratch3, FieldOperand(scratch2, CallHandlerInfo::kDataOffset));
558 __ push(scratch3);
559 } else {
560 __ push(Immediate(call_data));
561 }
562 // return value
563 __ push(Immediate(isolate->factory()->undefined_value()));
564 // return value default
565 __ push(Immediate(isolate->factory()->undefined_value()));
566 // isolate
567 __ push(Immediate(reinterpret_cast<int>(isolate)));
568 // holder
569 __ push(receiver);
570
571 // store receiver address for GenerateFastApiCallBody
572 ASSERT(!scratch1.is(eax));
573 __ mov(eax, esp);
574
575 // return address
576 __ push(scratch1);
577
578 GenerateFastApiCallBody(masm, optimization, argc, true);
579 }
580
581
582 static void GenerateFastApiCallBody(MacroAssembler* masm,
583 const CallOptimization& optimization,
584 int argc,
585 bool restore_context) {
586 // ----------- S t a t e -------------
587 // -- esp[0] : return address
588 // -- esp[4] - esp[28] : FunctionCallbackInfo, incl.
589 // : object passing the type check
590 // (set by CheckPrototypes)
591 // -- esp[32] : last argument
592 // -- ...
593 // -- esp[(argc + 7) * 4] : first argument
594 // -- esp[(argc + 8) * 4] : receiver
595 //
596 // -- eax : receiver address
597 // -----------------------------------
598 typedef FunctionCallbackArguments FCA;
599
502 // API function gets reference to the v8::Arguments. If CPU profiler 600 // API function gets reference to the v8::Arguments. If CPU profiler
503 // is enabled wrapper function will be called and we need to pass 601 // is enabled wrapper function will be called and we need to pass
504 // address of the callback as additional parameter, always allocate 602 // address of the callback as additional parameter, always allocate
505 // space for it. 603 // space for it.
506 const int kApiArgc = 1 + 1; 604 const int kApiArgc = 1 + 1;
507 605
508 // Allocate the v8::Arguments structure in the arguments' space since 606 // Allocate the v8::Arguments structure in the arguments' space since
509 // it's not controlled by GC. 607 // it's not controlled by GC.
510 const int kApiStackSpace = 4; 608 const int kApiStackSpace = 4;
511 609
610 Handle<CallHandlerInfo> api_call_info = optimization.api_call_info();
611
512 // Function address is a foreign pointer outside V8's heap. 612 // Function address is a foreign pointer outside V8's heap.
513 Address function_address = v8::ToCData<Address>(api_call_info->callback()); 613 Address function_address = v8::ToCData<Address>(api_call_info->callback());
514 __ PrepareCallApiFunction(kApiArgc + kApiStackSpace); 614 __ PrepareCallApiFunction(kApiArgc + kApiStackSpace);
515 615
516 // FunctionCallbackInfo::implicit_args_. 616 // FunctionCallbackInfo::implicit_args_.
517 __ mov(ApiParameterOperand(2), eax); 617 __ mov(ApiParameterOperand(2), eax);
518 __ add(eax, Immediate((argc + kFastApiCallArguments - 1) * kPointerSize)); 618 __ add(eax, Immediate((argc + kFastApiCallArguments - 1) * kPointerSize));
519 // FunctionCallbackInfo::values_. 619 // FunctionCallbackInfo::values_.
520 __ mov(ApiParameterOperand(3), eax); 620 __ mov(ApiParameterOperand(3), eax);
521 // FunctionCallbackInfo::length_. 621 // FunctionCallbackInfo::length_.
(...skipping 14 matching lines...) Expand all
536 __ CallApiFunctionAndReturn(function_address, 636 __ CallApiFunctionAndReturn(function_address,
537 thunk_address, 637 thunk_address,
538 ApiParameterOperand(1), 638 ApiParameterOperand(1),
539 argc + kFastApiCallArguments + 1, 639 argc + kFastApiCallArguments + 1,
540 return_value_operand, 640 return_value_operand,
541 restore_context ? 641 restore_context ?
542 &context_restore_operand : NULL); 642 &context_restore_operand : NULL);
543 } 643 }
544 644
545 645
546 // Generate call to api function.
547 static void GenerateFastApiCall(MacroAssembler* masm,
548 const CallOptimization& optimization,
549 Register receiver,
550 Register scratch,
551 int argc,
552 Register* values) {
553 ASSERT(optimization.is_simple_api_call());
554 ASSERT(!receiver.is(scratch));
555
556 const int stack_space = kFastApiCallArguments + argc + 1;
557 const int kHolderIndex = FunctionCallbackArguments::kHolderIndex + 1;
558 // Copy return value.
559 __ mov(scratch, Operand(esp, 0));
560 // Assign stack space for the call arguments.
561 __ sub(esp, Immediate(stack_space * kPointerSize));
562 // Move the return address on top of the stack.
563 __ mov(Operand(esp, 0), scratch);
564 // Write holder to stack frame.
565 __ mov(Operand(esp, kHolderIndex * kPointerSize), receiver);
566 // Write receiver to stack frame.
567 int index = stack_space;
568 __ mov(Operand(esp, index-- * kPointerSize), receiver);
569 // Write the arguments to stack frame.
570 for (int i = 0; i < argc; i++) {
571 ASSERT(!receiver.is(values[i]));
572 ASSERT(!scratch.is(values[i]));
573 __ mov(Operand(esp, index-- * kPointerSize), values[i]);
574 }
575
576 GenerateFastApiCall(masm, optimization, argc, true);
577 }
578
579
580 class CallInterceptorCompiler BASE_EMBEDDED { 646 class CallInterceptorCompiler BASE_EMBEDDED {
581 public: 647 public:
582 CallInterceptorCompiler(StubCompiler* stub_compiler, 648 CallInterceptorCompiler(StubCompiler* stub_compiler,
583 const ParameterCount& arguments, 649 const ParameterCount& arguments,
584 Register name, 650 Register name,
585 Code::ExtraICState extra_state) 651 Code::ExtraICState extra_state)
586 : stub_compiler_(stub_compiler), 652 : stub_compiler_(stub_compiler),
587 arguments_(arguments), 653 arguments_(arguments),
588 name_(name), 654 name_(name),
589 extra_state_(extra_state) {} 655 extra_state_(extra_state) {}
(...skipping 90 matching lines...) Expand 10 before | Expand all | Expand 10 after
680 } else { 746 } else {
681 // CheckPrototypes has a side effect of fetching a 'holder' 747 // CheckPrototypes has a side effect of fetching a 'holder'
682 // for API (object which is instanceof for the signature). It's 748 // for API (object which is instanceof for the signature). It's
683 // safe to omit it here, as if present, it should be fetched 749 // safe to omit it here, as if present, it should be fetched
684 // by the previous CheckPrototypes. 750 // by the previous CheckPrototypes.
685 ASSERT(depth2 == kInvalidProtoDepth); 751 ASSERT(depth2 == kInvalidProtoDepth);
686 } 752 }
687 753
688 // Invoke function. 754 // Invoke function.
689 if (can_do_fast_api_call) { 755 if (can_do_fast_api_call) {
690 GenerateFastApiCall(masm, optimization, arguments_.immediate(), false); 756 GenerateFastApiCall(masm, optimization, arguments_.immediate());
691 } else { 757 } else {
692 CallKind call_kind = CallICBase::Contextual::decode(extra_state_) 758 CallKind call_kind = CallICBase::Contextual::decode(extra_state_)
693 ? CALL_AS_FUNCTION 759 ? CALL_AS_FUNCTION
694 : CALL_AS_METHOD; 760 : CALL_AS_METHOD;
695 Handle<JSFunction> function = optimization.constant_function(); 761 Handle<JSFunction> function = optimization.constant_function();
696 ParameterCount expected(function); 762 ParameterCount expected(function);
697 __ InvokeFunction(function, expected, arguments_, 763 __ InvokeFunction(function, expected, arguments_,
698 JUMP_FUNCTION, NullCallWrapper(), call_kind); 764 JUMP_FUNCTION, NullCallWrapper(), call_kind);
699 } 765 }
700 766
(...skipping 559 matching lines...) Expand 10 before | Expand all | Expand 10 after
1260 // If we've skipped any global objects, it's not enough to verify that 1326 // If we've skipped any global objects, it's not enough to verify that
1261 // their maps haven't changed. We also need to check that the property 1327 // their maps haven't changed. We also need to check that the property
1262 // cell for the property is still empty. 1328 // cell for the property is still empty.
1263 GenerateCheckPropertyCells(masm(), object, holder, name, scratch1, miss); 1329 GenerateCheckPropertyCells(masm(), object, holder, name, scratch1, miss);
1264 1330
1265 // Return the register containing the holder. 1331 // Return the register containing the holder.
1266 return reg; 1332 return reg;
1267 } 1333 }
1268 1334
1269 1335
1270 void LoadStubCompiler::HandlerFrontendFooter(Handle<Name> name, 1336 void LoadStubCompiler::HandlerFrontendFooter(Handle<Name> name, Label* miss) {
1271 Label* success,
1272 Label* miss) {
1273 if (!miss->is_unused()) { 1337 if (!miss->is_unused()) {
1274 __ jmp(success); 1338 Label success;
1339 __ jmp(&success);
1275 __ bind(miss); 1340 __ bind(miss);
1276 TailCallBuiltin(masm(), MissBuiltin(kind())); 1341 TailCallBuiltin(masm(), MissBuiltin(kind()));
1342 __ bind(&success);
1277 } 1343 }
1278 } 1344 }
1279 1345
1280 1346
1281 void StoreStubCompiler::HandlerFrontendFooter(Handle<Name> name, 1347 void StoreStubCompiler::HandlerFrontendFooter(Handle<Name> name, Label* miss) {
1282 Label* success,
1283 Label* miss) {
1284 if (!miss->is_unused()) { 1348 if (!miss->is_unused()) {
1285 __ jmp(success); 1349 Label success;
1350 __ jmp(&success);
1286 GenerateRestoreName(masm(), miss, name); 1351 GenerateRestoreName(masm(), miss, name);
1287 TailCallBuiltin(masm(), MissBuiltin(kind())); 1352 TailCallBuiltin(masm(), MissBuiltin(kind()));
1353 __ bind(&success);
1288 } 1354 }
1289 } 1355 }
1290 1356
1291 1357
1292 Register LoadStubCompiler::CallbackHandlerFrontend( 1358 Register LoadStubCompiler::CallbackHandlerFrontend(
1293 Handle<JSObject> object, 1359 Handle<Object> object,
1294 Register object_reg, 1360 Register object_reg,
1295 Handle<JSObject> holder, 1361 Handle<JSObject> holder,
1296 Handle<Name> name, 1362 Handle<Name> name,
1297 Label* success,
1298 Handle<Object> callback) { 1363 Handle<Object> callback) {
1299 Label miss; 1364 Label miss;
1300 1365
1301 Register reg = HandlerFrontendHeader(object, object_reg, holder, name, &miss); 1366 Register reg = HandlerFrontendHeader(object, object_reg, holder, name, &miss);
1302 1367
1303 if (!holder->HasFastProperties() && !holder->IsJSGlobalObject()) { 1368 if (!holder->HasFastProperties() && !holder->IsJSGlobalObject()) {
1304 ASSERT(!reg.is(scratch2())); 1369 ASSERT(!reg.is(scratch2()));
1305 ASSERT(!reg.is(scratch3())); 1370 ASSERT(!reg.is(scratch3()));
1306 Register dictionary = scratch1(); 1371 Register dictionary = scratch1();
1307 bool must_preserve_dictionary_reg = reg.is(dictionary); 1372 bool must_preserve_dictionary_reg = reg.is(dictionary);
(...skipping 29 matching lines...) Expand all
1337 const int kValueOffset = kElementsStartOffset + kPointerSize; 1402 const int kValueOffset = kElementsStartOffset + kPointerSize;
1338 __ mov(scratch3(), 1403 __ mov(scratch3(),
1339 Operand(dictionary, index, times_4, kValueOffset - kHeapObjectTag)); 1404 Operand(dictionary, index, times_4, kValueOffset - kHeapObjectTag));
1340 if (must_preserve_dictionary_reg) { 1405 if (must_preserve_dictionary_reg) {
1341 __ pop(dictionary); 1406 __ pop(dictionary);
1342 } 1407 }
1343 __ cmp(scratch3(), callback); 1408 __ cmp(scratch3(), callback);
1344 __ j(not_equal, &miss); 1409 __ j(not_equal, &miss);
1345 } 1410 }
1346 1411
1347 HandlerFrontendFooter(name, success, &miss); 1412 HandlerFrontendFooter(name, &miss);
1348 return reg; 1413 return reg;
1349 } 1414 }
1350 1415
1351 1416
1352 void LoadStubCompiler::GenerateLoadField(Register reg, 1417 void LoadStubCompiler::GenerateLoadField(Register reg,
1353 Handle<JSObject> holder, 1418 Handle<JSObject> holder,
1354 PropertyIndex field, 1419 PropertyIndex field,
1355 Representation representation) { 1420 Representation representation) {
1356 if (!reg.is(receiver())) __ mov(receiver(), reg); 1421 if (!reg.is(receiver())) __ mov(receiver(), reg);
1357 if (kind() == Code::LOAD_IC) { 1422 if (kind() == Code::LOAD_IC) {
1358 LoadFieldStub stub(field.is_inobject(holder), 1423 LoadFieldStub stub(field.is_inobject(holder),
1359 field.translate(holder), 1424 field.translate(holder),
1360 representation); 1425 representation);
1361 GenerateTailCall(masm(), stub.GetCode(isolate())); 1426 GenerateTailCall(masm(), stub.GetCode(isolate()));
1362 } else { 1427 } else {
1363 KeyedLoadFieldStub stub(field.is_inobject(holder), 1428 KeyedLoadFieldStub stub(field.is_inobject(holder),
1364 field.translate(holder), 1429 field.translate(holder),
1365 representation); 1430 representation);
1366 GenerateTailCall(masm(), stub.GetCode(isolate())); 1431 GenerateTailCall(masm(), stub.GetCode(isolate()));
1367 } 1432 }
1368 } 1433 }
1369 1434
1370 1435
1371 void LoadStubCompiler::GenerateLoadCallback( 1436 void LoadStubCompiler::GenerateLoadCallback(
1372 const CallOptimization& call_optimization) { 1437 const CallOptimization& call_optimization) {
1373 GenerateFastApiCall( 1438 GenerateFastApiCall(
1374 masm(), call_optimization, receiver(), scratch3(), 0, NULL); 1439 masm(), call_optimization, receiver(), scratch1(),
1440 scratch2(), name(), 0, NULL);
1375 } 1441 }
1376 1442
1377 1443
1378 void LoadStubCompiler::GenerateLoadCallback( 1444 void LoadStubCompiler::GenerateLoadCallback(
1379 Register reg, 1445 Register reg,
1380 Handle<ExecutableAccessorInfo> callback) { 1446 Handle<ExecutableAccessorInfo> callback) {
1381 // Insert additional parameters into the stack frame above return address. 1447 // Insert additional parameters into the stack frame above return address.
1382 ASSERT(!scratch3().is(reg)); 1448 ASSERT(!scratch3().is(reg));
1383 __ pop(scratch3()); // Get return address to place it below. 1449 __ pop(scratch3()); // Get return address to place it below.
1384 1450
(...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after
1443 1509
1444 void LoadStubCompiler::GenerateLoadConstant(Handle<Object> value) { 1510 void LoadStubCompiler::GenerateLoadConstant(Handle<Object> value) {
1445 // Return the constant value. 1511 // Return the constant value.
1446 __ LoadObject(eax, value); 1512 __ LoadObject(eax, value);
1447 __ ret(0); 1513 __ ret(0);
1448 } 1514 }
1449 1515
1450 1516
1451 void LoadStubCompiler::GenerateLoadInterceptor( 1517 void LoadStubCompiler::GenerateLoadInterceptor(
1452 Register holder_reg, 1518 Register holder_reg,
1453 Handle<JSObject> object, 1519 Handle<Object> object,
1454 Handle<JSObject> interceptor_holder, 1520 Handle<JSObject> interceptor_holder,
1455 LookupResult* lookup, 1521 LookupResult* lookup,
1456 Handle<Name> name) { 1522 Handle<Name> name) {
1457 ASSERT(interceptor_holder->HasNamedInterceptor()); 1523 ASSERT(interceptor_holder->HasNamedInterceptor());
1458 ASSERT(!interceptor_holder->GetNamedInterceptor()->getter()->IsUndefined()); 1524 ASSERT(!interceptor_holder->GetNamedInterceptor()->getter()->IsUndefined());
1459 1525
1460 // So far the most popular follow ups for interceptor loads are FIELD 1526 // So far the most popular follow ups for interceptor loads are FIELD
1461 // and CALLBACKS, so inline only them, other cases may be added 1527 // and CALLBACKS, so inline only them, other cases may be added
1462 // later. 1528 // later.
1463 bool compile_followup_inline = false; 1529 bool compile_followup_inline = false;
(...skipping 201 matching lines...) Expand 10 before | Expand all | Expand 10 after
1665 ? CALL_AS_FUNCTION 1731 ? CALL_AS_FUNCTION
1666 : CALL_AS_METHOD; 1732 : CALL_AS_METHOD;
1667 __ InvokeFunction(edi, arguments(), JUMP_FUNCTION, 1733 __ InvokeFunction(edi, arguments(), JUMP_FUNCTION,
1668 NullCallWrapper(), call_kind); 1734 NullCallWrapper(), call_kind);
1669 1735
1670 // Handle call cache miss. 1736 // Handle call cache miss.
1671 __ bind(&miss); 1737 __ bind(&miss);
1672 GenerateMissBranch(); 1738 GenerateMissBranch();
1673 1739
1674 // Return the generated code. 1740 // Return the generated code.
1675 return GetCode(Code::FIELD, name); 1741 return GetCode(Code::FAST, name);
1676 } 1742 }
1677 1743
1678 1744
1679 Handle<Code> CallStubCompiler::CompileArrayCodeCall( 1745 Handle<Code> CallStubCompiler::CompileArrayCodeCall(
1680 Handle<Object> object, 1746 Handle<Object> object,
1681 Handle<JSObject> holder, 1747 Handle<JSObject> holder,
1682 Handle<Cell> cell, 1748 Handle<Cell> cell,
1683 Handle<JSFunction> function, 1749 Handle<JSFunction> function,
1684 Handle<String> name, 1750 Handle<String> name,
1685 Code::StubType type) { 1751 Code::StubType type) {
(...skipping 12 matching lines...) Expand all
1698 CheckPrototypes(Handle<JSObject>::cast(object), edx, holder, ebx, eax, edi, 1764 CheckPrototypes(Handle<JSObject>::cast(object), edx, holder, ebx, eax, edi,
1699 name, &miss); 1765 name, &miss);
1700 } else { 1766 } else {
1701 ASSERT(cell->value() == *function); 1767 ASSERT(cell->value() == *function);
1702 GenerateGlobalReceiverCheck(Handle<JSObject>::cast(object), holder, name, 1768 GenerateGlobalReceiverCheck(Handle<JSObject>::cast(object), holder, name,
1703 &miss); 1769 &miss);
1704 GenerateLoadFunctionFromCell(cell, function, &miss); 1770 GenerateLoadFunctionFromCell(cell, function, &miss);
1705 } 1771 }
1706 1772
1707 Handle<AllocationSite> site = isolate()->factory()->NewAllocationSite(); 1773 Handle<AllocationSite> site = isolate()->factory()->NewAllocationSite();
1708 site->set_transition_info(Smi::FromInt(GetInitialFastElementsKind())); 1774 site->SetElementsKind(GetInitialFastElementsKind());
1709 Handle<Cell> site_feedback_cell = isolate()->factory()->NewCell(site); 1775 Handle<Cell> site_feedback_cell = isolate()->factory()->NewCell(site);
1710 __ mov(eax, Immediate(argc)); 1776 __ mov(eax, Immediate(argc));
1711 __ mov(ebx, site_feedback_cell); 1777 __ mov(ebx, site_feedback_cell);
1712 __ mov(edi, function); 1778 __ mov(edi, function);
1713 1779
1714 ArrayConstructorStub stub(isolate()); 1780 ArrayConstructorStub stub(isolate());
1715 __ TailCallStub(&stub); 1781 __ TailCallStub(&stub);
1716 1782
1717 __ bind(&miss); 1783 __ bind(&miss);
1718 GenerateMissBranch(); 1784 GenerateMissBranch();
(...skipping 11 matching lines...) Expand all
1730 Handle<String> name, 1796 Handle<String> name,
1731 Code::StubType type) { 1797 Code::StubType type) {
1732 // ----------- S t a t e ------------- 1798 // ----------- S t a t e -------------
1733 // -- ecx : name 1799 // -- ecx : name
1734 // -- esp[0] : return address 1800 // -- esp[0] : return address
1735 // -- esp[(argc - n) * 4] : arg[n] (zero-based) 1801 // -- esp[(argc - n) * 4] : arg[n] (zero-based)
1736 // -- ... 1802 // -- ...
1737 // -- esp[(argc + 1) * 4] : receiver 1803 // -- esp[(argc + 1) * 4] : receiver
1738 // ----------------------------------- 1804 // -----------------------------------
1739 1805
1740 // If object is not an array, bail out to regular call. 1806 // If object is not an array or is observed, bail out to regular call.
1741 if (!object->IsJSArray() || !cell.is_null()) { 1807 if (!object->IsJSArray() ||
1808 !cell.is_null() ||
1809 Handle<JSArray>::cast(object)->map()->is_observed()) {
1742 return Handle<Code>::null(); 1810 return Handle<Code>::null();
1743 } 1811 }
1744 1812
1745 Label miss; 1813 Label miss;
1746 1814
1747 GenerateNameCheck(name, &miss); 1815 GenerateNameCheck(name, &miss);
1748 1816
1749 // Get the receiver from the stack. 1817 // Get the receiver from the stack.
1750 const int argc = arguments().immediate(); 1818 const int argc = arguments().immediate();
1751 __ mov(edx, Operand(esp, (argc + 1) * kPointerSize)); 1819 __ mov(edx, Operand(esp, (argc + 1) * kPointerSize));
(...skipping 237 matching lines...) Expand 10 before | Expand all | Expand 10 after
1989 Handle<String> name, 2057 Handle<String> name,
1990 Code::StubType type) { 2058 Code::StubType type) {
1991 // ----------- S t a t e ------------- 2059 // ----------- S t a t e -------------
1992 // -- ecx : name 2060 // -- ecx : name
1993 // -- esp[0] : return address 2061 // -- esp[0] : return address
1994 // -- esp[(argc - n) * 4] : arg[n] (zero-based) 2062 // -- esp[(argc - n) * 4] : arg[n] (zero-based)
1995 // -- ... 2063 // -- ...
1996 // -- esp[(argc + 1) * 4] : receiver 2064 // -- esp[(argc + 1) * 4] : receiver
1997 // ----------------------------------- 2065 // -----------------------------------
1998 2066
1999 // If object is not an array, bail out to regular call. 2067 // If object is not an array or is observed, bail out to regular call.
2000 if (!object->IsJSArray() || !cell.is_null()) { 2068 if (!object->IsJSArray() ||
2069 !cell.is_null() ||
2070 Handle<JSArray>::cast(object)->map()->is_observed()) {
2001 return Handle<Code>::null(); 2071 return Handle<Code>::null();
2002 } 2072 }
2003 2073
2004 Label miss, return_undefined, call_builtin; 2074 Label miss, return_undefined, call_builtin;
2005 2075
2006 GenerateNameCheck(name, &miss); 2076 GenerateNameCheck(name, &miss);
2007 2077
2008 // Get the receiver from the stack. 2078 // Get the receiver from the stack.
2009 const int argc = arguments().immediate(); 2079 const int argc = arguments().immediate();
2010 __ mov(edx, Operand(esp, (argc + 1) * kPointerSize)); 2080 __ mov(edx, Operand(esp, (argc + 1) * kPointerSize));
(...skipping 582 matching lines...) Expand 10 before | Expand all | Expand 10 after
2593 // Check that the maps haven't changed and find a Holder as a side effect. 2663 // Check that the maps haven't changed and find a Holder as a side effect.
2594 CheckPrototypes(Handle<JSObject>::cast(object), edx, holder, ebx, eax, edi, 2664 CheckPrototypes(Handle<JSObject>::cast(object), edx, holder, ebx, eax, edi,
2595 name, depth, &miss); 2665 name, depth, &miss);
2596 2666
2597 // Move the return address on top of the stack. 2667 // Move the return address on top of the stack.
2598 __ mov(eax, Operand(esp, kFastApiCallArguments * kPointerSize)); 2668 __ mov(eax, Operand(esp, kFastApiCallArguments * kPointerSize));
2599 __ mov(Operand(esp, 0 * kPointerSize), eax); 2669 __ mov(Operand(esp, 0 * kPointerSize), eax);
2600 2670
2601 // esp[2 * kPointerSize] is uninitialized, esp[3 * kPointerSize] contains 2671 // esp[2 * kPointerSize] is uninitialized, esp[3 * kPointerSize] contains
2602 // duplicate of return address and will be overwritten. 2672 // duplicate of return address and will be overwritten.
2603 GenerateFastApiCall(masm(), optimization, argc, false); 2673 GenerateFastApiCall(masm(), optimization, argc);
2604 2674
2605 __ bind(&miss); 2675 __ bind(&miss);
2606 __ add(esp, Immediate(kFastApiCallArguments * kPointerSize)); 2676 __ add(esp, Immediate(kFastApiCallArguments * kPointerSize));
2607 2677
2608 __ bind(&miss_before_stack_reserved); 2678 __ bind(&miss_before_stack_reserved);
2609 GenerateMissBranch(); 2679 GenerateMissBranch();
2610 2680
2611 // Return the generated code. 2681 // Return the generated code.
2612 return GetCode(function); 2682 return GetCode(function);
2613 } 2683 }
2614 2684
2615 2685
2686 void StubCompiler::GenerateBooleanCheck(Register object, Label* miss) {
2687 Label success;
2688 // Check that the object is a boolean.
2689 __ cmp(object, factory()->true_value());
2690 __ j(equal, &success);
2691 __ cmp(object, factory()->false_value());
2692 __ j(not_equal, miss);
2693 __ bind(&success);
2694 }
2695
2696
2616 void CallStubCompiler::CompileHandlerFrontend(Handle<Object> object, 2697 void CallStubCompiler::CompileHandlerFrontend(Handle<Object> object,
2617 Handle<JSObject> holder, 2698 Handle<JSObject> holder,
2618 Handle<Name> name, 2699 Handle<Name> name,
2619 CheckType check, 2700 CheckType check) {
2620 Label* success) {
2621 // ----------- S t a t e ------------- 2701 // ----------- S t a t e -------------
2622 // -- ecx : name 2702 // -- ecx : name
2623 // -- esp[0] : return address 2703 // -- esp[0] : return address
2624 // -- esp[(argc - n) * 4] : arg[n] (zero-based) 2704 // -- esp[(argc - n) * 4] : arg[n] (zero-based)
2625 // -- ... 2705 // -- ...
2626 // -- esp[(argc + 1) * 4] : receiver 2706 // -- esp[(argc + 1) * 4] : receiver
2627 // ----------------------------------- 2707 // -----------------------------------
2628 Label miss; 2708 Label miss;
2629 GenerateNameCheck(name, &miss); 2709 GenerateNameCheck(name, &miss);
2630 2710
(...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after
2689 __ bind(&fast); 2769 __ bind(&fast);
2690 // Check that the maps starting from the prototype haven't changed. 2770 // Check that the maps starting from the prototype haven't changed.
2691 GenerateDirectLoadGlobalFunctionPrototype( 2771 GenerateDirectLoadGlobalFunctionPrototype(
2692 masm(), Context::NUMBER_FUNCTION_INDEX, eax, &miss); 2772 masm(), Context::NUMBER_FUNCTION_INDEX, eax, &miss);
2693 CheckPrototypes( 2773 CheckPrototypes(
2694 Handle<JSObject>(JSObject::cast(object->GetPrototype(isolate()))), 2774 Handle<JSObject>(JSObject::cast(object->GetPrototype(isolate()))),
2695 eax, holder, ebx, edx, edi, name, &miss); 2775 eax, holder, ebx, edx, edi, name, &miss);
2696 break; 2776 break;
2697 } 2777 }
2698 case BOOLEAN_CHECK: { 2778 case BOOLEAN_CHECK: {
2699 Label fast; 2779 GenerateBooleanCheck(edx, &miss);
2700 // Check that the object is a boolean.
2701 __ cmp(edx, factory()->true_value());
2702 __ j(equal, &fast);
2703 __ cmp(edx, factory()->false_value());
2704 __ j(not_equal, &miss);
2705 __ bind(&fast);
2706 // Check that the maps starting from the prototype haven't changed. 2780 // Check that the maps starting from the prototype haven't changed.
2707 GenerateDirectLoadGlobalFunctionPrototype( 2781 GenerateDirectLoadGlobalFunctionPrototype(
2708 masm(), Context::BOOLEAN_FUNCTION_INDEX, eax, &miss); 2782 masm(), Context::BOOLEAN_FUNCTION_INDEX, eax, &miss);
2709 CheckPrototypes( 2783 CheckPrototypes(
2710 Handle<JSObject>(JSObject::cast(object->GetPrototype(isolate()))), 2784 Handle<JSObject>(JSObject::cast(object->GetPrototype(isolate()))),
2711 eax, holder, ebx, edx, edi, name, &miss); 2785 eax, holder, ebx, edx, edi, name, &miss);
2712 break; 2786 break;
2713 } 2787 }
2714 } 2788 }
2715 2789
2716 __ jmp(success); 2790 Label success;
2791 __ jmp(&success);
2717 2792
2718 // Handle call cache miss. 2793 // Handle call cache miss.
2719 __ bind(&miss); 2794 __ bind(&miss);
2720 GenerateMissBranch(); 2795 GenerateMissBranch();
2796
2797 __ bind(&success);
2721 } 2798 }
2722 2799
2723 2800
2724 void CallStubCompiler::CompileHandlerBackend(Handle<JSFunction> function) { 2801 void CallStubCompiler::CompileHandlerBackend(Handle<JSFunction> function) {
2725 CallKind call_kind = CallICBase::Contextual::decode(extra_state_) 2802 CallKind call_kind = CallICBase::Contextual::decode(extra_state_)
2726 ? CALL_AS_FUNCTION 2803 ? CALL_AS_FUNCTION
2727 : CALL_AS_METHOD; 2804 : CALL_AS_METHOD;
2728 ParameterCount expected(function); 2805 ParameterCount expected(function);
2729 __ InvokeFunction(function, expected, arguments(), 2806 __ InvokeFunction(function, expected, arguments(),
2730 JUMP_FUNCTION, NullCallWrapper(), call_kind); 2807 JUMP_FUNCTION, NullCallWrapper(), call_kind);
2731 } 2808 }
2732 2809
2733 2810
2734 Handle<Code> CallStubCompiler::CompileCallConstant( 2811 Handle<Code> CallStubCompiler::CompileCallConstant(
2735 Handle<Object> object, 2812 Handle<Object> object,
2736 Handle<JSObject> holder, 2813 Handle<JSObject> holder,
2737 Handle<Name> name, 2814 Handle<Name> name,
2738 CheckType check, 2815 CheckType check,
2739 Handle<JSFunction> function) { 2816 Handle<JSFunction> function) {
2740 2817
2741 if (HasCustomCallGenerator(function)) { 2818 if (HasCustomCallGenerator(function)) {
2742 Handle<Code> code = CompileCustomCall(object, holder, 2819 Handle<Code> code = CompileCustomCall(object, holder,
2743 Handle<Cell>::null(), 2820 Handle<Cell>::null(),
2744 function, Handle<String>::cast(name), 2821 function, Handle<String>::cast(name),
2745 Code::CONSTANT); 2822 Code::FAST);
2746 // A null handle means bail out to the regular compiler code below. 2823 // A null handle means bail out to the regular compiler code below.
2747 if (!code.is_null()) return code; 2824 if (!code.is_null()) return code;
2748 } 2825 }
2749 2826
2750 Label success; 2827 CompileHandlerFrontend(object, holder, name, check);
2751
2752 CompileHandlerFrontend(object, holder, name, check, &success);
2753 __ bind(&success);
2754 CompileHandlerBackend(function); 2828 CompileHandlerBackend(function);
2755 2829
2756 // Return the generated code. 2830 // Return the generated code.
2757 return GetCode(function); 2831 return GetCode(function);
2758 } 2832 }
2759 2833
2760 2834
2761 Handle<Code> CallStubCompiler::CompileCallInterceptor(Handle<JSObject> object, 2835 Handle<Code> CallStubCompiler::CompileCallInterceptor(Handle<JSObject> object,
2762 Handle<JSObject> holder, 2836 Handle<JSObject> holder,
2763 Handle<Name> name) { 2837 Handle<Name> name) {
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after
2806 ? CALL_AS_FUNCTION 2880 ? CALL_AS_FUNCTION
2807 : CALL_AS_METHOD; 2881 : CALL_AS_METHOD;
2808 __ InvokeFunction(edi, arguments(), JUMP_FUNCTION, 2882 __ InvokeFunction(edi, arguments(), JUMP_FUNCTION,
2809 NullCallWrapper(), call_kind); 2883 NullCallWrapper(), call_kind);
2810 2884
2811 // Handle load cache miss. 2885 // Handle load cache miss.
2812 __ bind(&miss); 2886 __ bind(&miss);
2813 GenerateMissBranch(); 2887 GenerateMissBranch();
2814 2888
2815 // Return the generated code. 2889 // Return the generated code.
2816 return GetCode(Code::INTERCEPTOR, name); 2890 return GetCode(Code::FAST, name);
2817 } 2891 }
2818 2892
2819 2893
2820 Handle<Code> CallStubCompiler::CompileCallGlobal( 2894 Handle<Code> CallStubCompiler::CompileCallGlobal(
2821 Handle<JSObject> object, 2895 Handle<JSObject> object,
2822 Handle<GlobalObject> holder, 2896 Handle<GlobalObject> holder,
2823 Handle<PropertyCell> cell, 2897 Handle<PropertyCell> cell,
2824 Handle<JSFunction> function, 2898 Handle<JSFunction> function,
2825 Handle<Name> name) { 2899 Handle<Name> name) {
2826 // ----------- S t a t e ------------- 2900 // ----------- S t a t e -------------
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after
2878 // Return the generated code. 2952 // Return the generated code.
2879 return GetCode(Code::NORMAL, name); 2953 return GetCode(Code::NORMAL, name);
2880 } 2954 }
2881 2955
2882 2956
2883 Handle<Code> StoreStubCompiler::CompileStoreCallback( 2957 Handle<Code> StoreStubCompiler::CompileStoreCallback(
2884 Handle<JSObject> object, 2958 Handle<JSObject> object,
2885 Handle<JSObject> holder, 2959 Handle<JSObject> holder,
2886 Handle<Name> name, 2960 Handle<Name> name,
2887 Handle<ExecutableAccessorInfo> callback) { 2961 Handle<ExecutableAccessorInfo> callback) {
2888 Label success; 2962 HandlerFrontend(object, receiver(), holder, name);
2889 HandlerFrontend(object, receiver(), holder, name, &success);
2890 __ bind(&success);
2891 2963
2892 __ pop(scratch1()); // remove the return address 2964 __ pop(scratch1()); // remove the return address
2893 __ push(receiver()); 2965 __ push(receiver());
2894 __ Push(callback); 2966 __ Push(callback);
2895 __ Push(name); 2967 __ Push(name);
2896 __ push(value()); 2968 __ push(value());
2897 __ push(scratch1()); // restore return address 2969 __ push(scratch1()); // restore return address
2898 2970
2899 // Do tail-call to the runtime system. 2971 // Do tail-call to the runtime system.
2900 ExternalReference store_callback_property = 2972 ExternalReference store_callback_property =
2901 ExternalReference(IC_Utility(IC::kStoreCallbackProperty), isolate()); 2973 ExternalReference(IC_Utility(IC::kStoreCallbackProperty), isolate());
2902 __ TailCallExternalReference(store_callback_property, 4, 1); 2974 __ TailCallExternalReference(store_callback_property, 4, 1);
2903 2975
2904 // Return the generated code. 2976 // Return the generated code.
2905 return GetCode(kind(), Code::CALLBACKS, name); 2977 return GetCode(kind(), Code::FAST, name);
2906 } 2978 }
2907 2979
2908 2980
2909 Handle<Code> StoreStubCompiler::CompileStoreCallback( 2981 Handle<Code> StoreStubCompiler::CompileStoreCallback(
2910 Handle<JSObject> object, 2982 Handle<JSObject> object,
2911 Handle<JSObject> holder, 2983 Handle<JSObject> holder,
2912 Handle<Name> name, 2984 Handle<Name> name,
2913 const CallOptimization& call_optimization) { 2985 const CallOptimization& call_optimization) {
2914 Label success; 2986 HandlerFrontend(object, receiver(), holder, name);
2915 HandlerFrontend(object, receiver(), holder, name, &success);
2916 __ bind(&success);
2917 2987
2918 Register values[] = { value() }; 2988 Register values[] = { value() };
2919 GenerateFastApiCall( 2989 GenerateFastApiCall(
2920 masm(), call_optimization, receiver(), scratch1(), 1, values); 2990 masm(), call_optimization, receiver(), scratch1(),
2991 scratch2(), this->name(), 1, values);
2921 2992
2922 // Return the generated code. 2993 // Return the generated code.
2923 return GetCode(kind(), Code::CALLBACKS, name); 2994 return GetCode(kind(), Code::FAST, name);
2924 } 2995 }
2925 2996
2926 2997
2927 #undef __ 2998 #undef __
2928 #define __ ACCESS_MASM(masm) 2999 #define __ ACCESS_MASM(masm)
2929 3000
2930 3001
2931 void StoreStubCompiler::GenerateStoreViaSetter( 3002 void StoreStubCompiler::GenerateStoreViaSetter(
2932 MacroAssembler* masm, 3003 MacroAssembler* masm,
2933 Handle<JSFunction> setter) { 3004 Handle<JSFunction> setter) {
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after
2980 __ push(value()); 3051 __ push(value());
2981 __ push(Immediate(Smi::FromInt(strict_mode()))); 3052 __ push(Immediate(Smi::FromInt(strict_mode())));
2982 __ push(scratch1()); // restore return address 3053 __ push(scratch1()); // restore return address
2983 3054
2984 // Do tail-call to the runtime system. 3055 // Do tail-call to the runtime system.
2985 ExternalReference store_ic_property = 3056 ExternalReference store_ic_property =
2986 ExternalReference(IC_Utility(IC::kStoreInterceptorProperty), isolate()); 3057 ExternalReference(IC_Utility(IC::kStoreInterceptorProperty), isolate());
2987 __ TailCallExternalReference(store_ic_property, 4, 1); 3058 __ TailCallExternalReference(store_ic_property, 4, 1);
2988 3059
2989 // Return the generated code. 3060 // Return the generated code.
2990 return GetCode(kind(), Code::INTERCEPTOR, name); 3061 return GetCode(kind(), Code::FAST, name);
2991 } 3062 }
2992 3063
2993 3064
2994 Handle<Code> KeyedStoreStubCompiler::CompileStorePolymorphic( 3065 Handle<Code> KeyedStoreStubCompiler::CompileStorePolymorphic(
2995 MapHandleList* receiver_maps, 3066 MapHandleList* receiver_maps,
2996 CodeHandleList* handler_stubs, 3067 CodeHandleList* handler_stubs,
2997 MapHandleList* transitioned_maps) { 3068 MapHandleList* transitioned_maps) {
2998 Label miss; 3069 Label miss;
2999 __ JumpIfSmi(receiver(), &miss, Label::kNear); 3070 __ JumpIfSmi(receiver(), &miss, Label::kNear);
3000 __ mov(scratch1(), FieldOperand(receiver(), HeapObject::kMapOffset)); 3071 __ mov(scratch1(), FieldOperand(receiver(), HeapObject::kMapOffset));
(...skipping 12 matching lines...) Expand all
3013 __ bind(&miss); 3084 __ bind(&miss);
3014 TailCallBuiltin(masm(), MissBuiltin(kind())); 3085 TailCallBuiltin(masm(), MissBuiltin(kind()));
3015 3086
3016 // Return the generated code. 3087 // Return the generated code.
3017 return GetICCode( 3088 return GetICCode(
3018 kind(), Code::NORMAL, factory()->empty_string(), POLYMORPHIC); 3089 kind(), Code::NORMAL, factory()->empty_string(), POLYMORPHIC);
3019 } 3090 }
3020 3091
3021 3092
3022 Handle<Code> LoadStubCompiler::CompileLoadNonexistent( 3093 Handle<Code> LoadStubCompiler::CompileLoadNonexistent(
3023 Handle<JSObject> object, 3094 Handle<Object> object,
3024 Handle<JSObject> last, 3095 Handle<JSObject> last,
3025 Handle<Name> name, 3096 Handle<Name> name,
3026 Handle<JSGlobalObject> global) { 3097 Handle<JSGlobalObject> global) {
3027 Label success; 3098 NonexistentHandlerFrontend(object, last, name, global);
3028 3099
3029 NonexistentHandlerFrontend(object, last, name, &success, global);
3030
3031 __ bind(&success);
3032 // Return undefined if maps of the full prototype chain are still the 3100 // Return undefined if maps of the full prototype chain are still the
3033 // same and no global property with this name contains a value. 3101 // same and no global property with this name contains a value.
3034 __ mov(eax, isolate()->factory()->undefined_value()); 3102 __ mov(eax, isolate()->factory()->undefined_value());
3035 __ ret(0); 3103 __ ret(0);
3036 3104
3037 // Return the generated code. 3105 // Return the generated code.
3038 return GetCode(kind(), Code::NONEXISTENT, name); 3106 return GetCode(kind(), Code::FAST, name);
3039 } 3107 }
3040 3108
3041 3109
3042 Register* LoadStubCompiler::registers() { 3110 Register* LoadStubCompiler::registers() {
3043 // receiver, name, scratch1, scratch2, scratch3, scratch4. 3111 // receiver, name, scratch1, scratch2, scratch3, scratch4.
3044 static Register registers[] = { edx, ecx, ebx, eax, edi, no_reg }; 3112 static Register registers[] = { edx, ecx, ebx, eax, edi, no_reg };
3045 return registers; 3113 return registers;
3046 } 3114 }
3047 3115
3048 3116
(...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after
3111 } 3179 }
3112 __ ret(0); 3180 __ ret(0);
3113 } 3181 }
3114 3182
3115 3183
3116 #undef __ 3184 #undef __
3117 #define __ ACCESS_MASM(masm()) 3185 #define __ ACCESS_MASM(masm())
3118 3186
3119 3187
3120 Handle<Code> LoadStubCompiler::CompileLoadGlobal( 3188 Handle<Code> LoadStubCompiler::CompileLoadGlobal(
3121 Handle<JSObject> object, 3189 Handle<Object> object,
3122 Handle<GlobalObject> global, 3190 Handle<GlobalObject> global,
3123 Handle<PropertyCell> cell, 3191 Handle<PropertyCell> cell,
3124 Handle<Name> name, 3192 Handle<Name> name,
3125 bool is_dont_delete) { 3193 bool is_dont_delete) {
3126 Label success, miss; 3194 Label miss;
3127 3195
3128 HandlerFrontendHeader(object, receiver(), global, name, &miss); 3196 HandlerFrontendHeader(object, receiver(), global, name, &miss);
3129 // Get the value from the cell. 3197 // Get the value from the cell.
3130 if (Serializer::enabled()) { 3198 if (Serializer::enabled()) {
3131 __ mov(eax, Immediate(cell)); 3199 __ mov(eax, Immediate(cell));
3132 __ mov(eax, FieldOperand(eax, PropertyCell::kValueOffset)); 3200 __ mov(eax, FieldOperand(eax, PropertyCell::kValueOffset));
3133 } else { 3201 } else {
3134 __ mov(eax, Operand::ForCell(cell)); 3202 __ mov(eax, Operand::ForCell(cell));
3135 } 3203 }
3136 3204
3137 // Check for deleted property if property can actually be deleted. 3205 // Check for deleted property if property can actually be deleted.
3138 if (!is_dont_delete) { 3206 if (!is_dont_delete) {
3139 __ cmp(eax, factory()->the_hole_value()); 3207 __ cmp(eax, factory()->the_hole_value());
3140 __ j(equal, &miss); 3208 __ j(equal, &miss);
3141 } else if (FLAG_debug_code) { 3209 } else if (FLAG_debug_code) {
3142 __ cmp(eax, factory()->the_hole_value()); 3210 __ cmp(eax, factory()->the_hole_value());
3143 __ Check(not_equal, kDontDeleteCellsCannotContainTheHole); 3211 __ Check(not_equal, kDontDeleteCellsCannotContainTheHole);
3144 } 3212 }
3145 3213
3146 HandlerFrontendFooter(name, &success, &miss); 3214 HandlerFrontendFooter(name, &miss);
3147 __ bind(&success);
3148 3215
3149 Counters* counters = isolate()->counters(); 3216 Counters* counters = isolate()->counters();
3150 __ IncrementCounter(counters->named_load_global_stub(), 1); 3217 __ IncrementCounter(counters->named_load_global_stub(), 1);
3151 // The code above already loads the result into the return register. 3218 // The code above already loads the result into the return register.
3152 __ ret(0); 3219 __ ret(0);
3153 3220
3154 // Return the generated code. 3221 // Return the generated code.
3155 return GetCode(kind(), Code::NORMAL, name); 3222 return GetCode(kind(), Code::NORMAL, name);
3156 } 3223 }
3157 3224
3158 3225
3159 Handle<Code> BaseLoadStoreStubCompiler::CompilePolymorphicIC( 3226 Handle<Code> BaseLoadStoreStubCompiler::CompilePolymorphicIC(
3160 MapHandleList* receiver_maps, 3227 TypeHandleList* types,
3161 CodeHandleList* handlers, 3228 CodeHandleList* handlers,
3162 Handle<Name> name, 3229 Handle<Name> name,
3163 Code::StubType type, 3230 Code::StubType type,
3164 IcCheckType check) { 3231 IcCheckType check) {
3165 Label miss; 3232 Label miss;
3166 3233
3167 if (check == PROPERTY) { 3234 if (check == PROPERTY) {
3168 GenerateNameCheck(name, this->name(), &miss); 3235 GenerateNameCheck(name, this->name(), &miss);
3169 } 3236 }
3170 3237
3171 __ JumpIfSmi(receiver(), &miss); 3238 Label number_case;
3239 Label* smi_target = IncludesNumberType(types) ? &number_case : &miss;
3240 __ JumpIfSmi(receiver(), smi_target);
3241
3172 Register map_reg = scratch1(); 3242 Register map_reg = scratch1();
3173 __ mov(map_reg, FieldOperand(receiver(), HeapObject::kMapOffset)); 3243 __ mov(map_reg, FieldOperand(receiver(), HeapObject::kMapOffset));
3174 int receiver_count = receiver_maps->length(); 3244 int receiver_count = types->length();
3175 int number_of_handled_maps = 0; 3245 int number_of_handled_maps = 0;
3176 for (int current = 0; current < receiver_count; ++current) { 3246 for (int current = 0; current < receiver_count; ++current) {
3177 Handle<Map> map = receiver_maps->at(current); 3247 Handle<Type> type = types->at(current);
3248 Handle<Map> map = IC::TypeToMap(*type, isolate());
3178 if (!map->is_deprecated()) { 3249 if (!map->is_deprecated()) {
3179 number_of_handled_maps++; 3250 number_of_handled_maps++;
3180 __ cmp(map_reg, map); 3251 __ cmp(map_reg, map);
3252 if (type->Is(Type::Number())) {
3253 ASSERT(!number_case.is_unused());
3254 __ bind(&number_case);
3255 }
3181 __ j(equal, handlers->at(current)); 3256 __ j(equal, handlers->at(current));
3182 } 3257 }
3183 } 3258 }
3184 ASSERT(number_of_handled_maps != 0); 3259 ASSERT(number_of_handled_maps != 0);
3185 3260
3186 __ bind(&miss); 3261 __ bind(&miss);
3187 TailCallBuiltin(masm(), MissBuiltin(kind())); 3262 TailCallBuiltin(masm(), MissBuiltin(kind()));
3188 3263
3189 // Return the generated code. 3264 // Return the generated code.
3190 InlineCacheState state = 3265 InlineCacheState state =
3191 number_of_handled_maps > 1 ? POLYMORPHIC : MONOMORPHIC; 3266 number_of_handled_maps > 1 ? POLYMORPHIC : MONOMORPHIC;
3192 return GetICCode(kind(), type, name, state); 3267 return GetICCode(kind(), type, name, state);
3193 } 3268 }
3194 3269
3195 3270
3196 #undef __ 3271 #undef __
3197 #define __ ACCESS_MASM(masm) 3272 #define __ ACCESS_MASM(masm)
3198 3273
3199 3274
3200 void KeyedLoadStubCompiler::GenerateLoadDictionaryElement( 3275 void KeyedLoadStubCompiler::GenerateLoadDictionaryElement(
3201 MacroAssembler* masm) { 3276 MacroAssembler* masm) {
3202 // ----------- S t a t e ------------- 3277 // ----------- S t a t e -------------
3203 // -- ecx : key 3278 // -- ecx : key
3204 // -- edx : receiver 3279 // -- edx : receiver
3205 // -- esp[0] : return address 3280 // -- esp[0] : return address
3206 // ----------------------------------- 3281 // -----------------------------------
3207 Label slow, miss_force_generic; 3282 Label slow, miss;
3208 3283
3209 // This stub is meant to be tail-jumped to, the receiver must already 3284 // This stub is meant to be tail-jumped to, the receiver must already
3210 // have been verified by the caller to not be a smi. 3285 // have been verified by the caller to not be a smi.
3211 __ JumpIfNotSmi(ecx, &miss_force_generic); 3286 __ JumpIfNotSmi(ecx, &miss);
3212 __ mov(ebx, ecx); 3287 __ mov(ebx, ecx);
3213 __ SmiUntag(ebx); 3288 __ SmiUntag(ebx);
3214 __ mov(eax, FieldOperand(edx, JSObject::kElementsOffset)); 3289 __ mov(eax, FieldOperand(edx, JSObject::kElementsOffset));
3215 3290
3216 // Push receiver on the stack to free up a register for the dictionary 3291 // Push receiver on the stack to free up a register for the dictionary
3217 // probing. 3292 // probing.
3218 __ push(edx); 3293 __ push(edx);
3219 __ LoadFromNumberDictionary(&slow, eax, ecx, ebx, edx, edi, eax); 3294 __ LoadFromNumberDictionary(&slow, eax, ecx, ebx, edx, edi, eax);
3220 // Pop receiver before returning. 3295 // Pop receiver before returning.
3221 __ pop(edx); 3296 __ pop(edx);
3222 __ ret(0); 3297 __ ret(0);
3223 3298
3224 __ bind(&slow); 3299 __ bind(&slow);
3225 __ pop(edx); 3300 __ pop(edx);
3226 3301
3227 // ----------- S t a t e ------------- 3302 // ----------- S t a t e -------------
3228 // -- ecx : key 3303 // -- ecx : key
3229 // -- edx : receiver 3304 // -- edx : receiver
3230 // -- esp[0] : return address 3305 // -- esp[0] : return address
3231 // ----------------------------------- 3306 // -----------------------------------
3232 TailCallBuiltin(masm, Builtins::kKeyedLoadIC_Slow); 3307 TailCallBuiltin(masm, Builtins::kKeyedLoadIC_Slow);
3233 3308
3234 __ bind(&miss_force_generic); 3309 __ bind(&miss);
3235 // ----------- S t a t e ------------- 3310 // ----------- S t a t e -------------
3236 // -- ecx : key 3311 // -- ecx : key
3237 // -- edx : receiver 3312 // -- edx : receiver
3238 // -- esp[0] : return address 3313 // -- esp[0] : return address
3239 // ----------------------------------- 3314 // -----------------------------------
3240 TailCallBuiltin(masm, Builtins::kKeyedLoadIC_MissForceGeneric); 3315 TailCallBuiltin(masm, Builtins::kKeyedLoadIC_Miss);
3241 } 3316 }
3242 3317
3243 3318
3244 #undef __ 3319 #undef __
3245 3320
3246 } } // namespace v8::internal 3321 } } // namespace v8::internal
3247 3322
3248 #endif // V8_TARGET_ARCH_IA32 3323 #endif // V8_TARGET_ARCH_IA32
OLDNEW
« include/v8-platform.h ('K') | « src/ia32/macro-assembler-ia32.cc ('k') | src/ic.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698