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

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

Issue 149133004: A64: Synchronize with r17807. (Closed) Base URL: https://v8.googlecode.com/svn/branches/experimental/a64
Patch Set: 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/macro-assembler-x64.cc ('k') | test/cctest/cctest.h » ('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 1182 matching lines...) Expand 10 before | Expand all | Expand 10 after
1193 // If we've skipped any global objects, it's not enough to verify that 1193 // If we've skipped any global objects, it's not enough to verify that
1194 // their maps haven't changed. We also need to check that the property 1194 // their maps haven't changed. We also need to check that the property
1195 // cell for the property is still empty. 1195 // cell for the property is still empty.
1196 GenerateCheckPropertyCells(masm(), object, holder, name, scratch1, miss); 1196 GenerateCheckPropertyCells(masm(), object, holder, name, scratch1, miss);
1197 1197
1198 // Return the register containing the holder. 1198 // Return the register containing the holder.
1199 return reg; 1199 return reg;
1200 } 1200 }
1201 1201
1202 1202
1203 void LoadStubCompiler::HandlerFrontendFooter(Handle<Name> name, 1203 void LoadStubCompiler::HandlerFrontendFooter(Handle<Name> name, Label* miss) {
1204 Label* success,
1205 Label* miss) {
1206 if (!miss->is_unused()) { 1204 if (!miss->is_unused()) {
1207 __ jmp(success); 1205 Label success;
1206 __ jmp(&success);
1208 __ bind(miss); 1207 __ bind(miss);
1209 TailCallBuiltin(masm(), MissBuiltin(kind())); 1208 TailCallBuiltin(masm(), MissBuiltin(kind()));
1209 __ bind(&success);
1210 } 1210 }
1211 } 1211 }
1212 1212
1213 1213
1214 void StoreStubCompiler::HandlerFrontendFooter(Handle<Name> name, 1214 void StoreStubCompiler::HandlerFrontendFooter(Handle<Name> name, Label* miss) {
1215 Label* success,
1216 Label* miss) {
1217 if (!miss->is_unused()) { 1215 if (!miss->is_unused()) {
1218 __ jmp(success); 1216 Label success;
1217 __ jmp(&success);
1219 GenerateRestoreName(masm(), miss, name); 1218 GenerateRestoreName(masm(), miss, name);
1220 TailCallBuiltin(masm(), MissBuiltin(kind())); 1219 TailCallBuiltin(masm(), MissBuiltin(kind()));
1220 __ bind(&success);
1221 } 1221 }
1222 } 1222 }
1223 1223
1224 1224
1225 Register LoadStubCompiler::CallbackHandlerFrontend( 1225 Register LoadStubCompiler::CallbackHandlerFrontend(
1226 Handle<JSObject> object, 1226 Handle<Object> object,
1227 Register object_reg, 1227 Register object_reg,
1228 Handle<JSObject> holder, 1228 Handle<JSObject> holder,
1229 Handle<Name> name, 1229 Handle<Name> name,
1230 Label* success,
1231 Handle<Object> callback) { 1230 Handle<Object> callback) {
1232 Label miss; 1231 Label miss;
1233 1232
1234 Register reg = HandlerFrontendHeader(object, object_reg, holder, name, &miss); 1233 Register reg = HandlerFrontendHeader(object, object_reg, holder, name, &miss);
1235 1234
1236 if (!holder->HasFastProperties() && !holder->IsJSGlobalObject()) { 1235 if (!holder->HasFastProperties() && !holder->IsJSGlobalObject()) {
1237 ASSERT(!reg.is(scratch2())); 1236 ASSERT(!reg.is(scratch2()));
1238 ASSERT(!reg.is(scratch3())); 1237 ASSERT(!reg.is(scratch3()));
1239 ASSERT(!reg.is(scratch4())); 1238 ASSERT(!reg.is(scratch4()));
1240 1239
(...skipping 20 matching lines...) Expand all
1261 NameDictionary::kElementsStartIndex * kPointerSize; 1260 NameDictionary::kElementsStartIndex * kPointerSize;
1262 const int kValueOffset = kElementsStartOffset + kPointerSize; 1261 const int kValueOffset = kElementsStartOffset + kPointerSize;
1263 __ movq(scratch2(), 1262 __ movq(scratch2(),
1264 Operand(dictionary, index, times_pointer_size, 1263 Operand(dictionary, index, times_pointer_size,
1265 kValueOffset - kHeapObjectTag)); 1264 kValueOffset - kHeapObjectTag));
1266 __ movq(scratch3(), callback, RelocInfo::EMBEDDED_OBJECT); 1265 __ movq(scratch3(), callback, RelocInfo::EMBEDDED_OBJECT);
1267 __ cmpq(scratch2(), scratch3()); 1266 __ cmpq(scratch2(), scratch3());
1268 __ j(not_equal, &miss); 1267 __ j(not_equal, &miss);
1269 } 1268 }
1270 1269
1271 HandlerFrontendFooter(name, success, &miss); 1270 HandlerFrontendFooter(name, &miss);
1272 return reg; 1271 return reg;
1273 } 1272 }
1274 1273
1275 1274
1276 void LoadStubCompiler::GenerateLoadField(Register reg, 1275 void LoadStubCompiler::GenerateLoadField(Register reg,
1277 Handle<JSObject> holder, 1276 Handle<JSObject> holder,
1278 PropertyIndex field, 1277 PropertyIndex field,
1279 Representation representation) { 1278 Representation representation) {
1280 if (!reg.is(receiver())) __ movq(receiver(), reg); 1279 if (!reg.is(receiver())) __ movq(receiver(), reg);
1281 if (kind() == Code::LOAD_IC) { 1280 if (kind() == Code::LOAD_IC) {
(...skipping 100 matching lines...) Expand 10 before | Expand all | Expand 10 after
1382 1381
1383 void LoadStubCompiler::GenerateLoadConstant(Handle<Object> value) { 1382 void LoadStubCompiler::GenerateLoadConstant(Handle<Object> value) {
1384 // Return the constant value. 1383 // Return the constant value.
1385 __ Move(rax, value); 1384 __ Move(rax, value);
1386 __ ret(0); 1385 __ ret(0);
1387 } 1386 }
1388 1387
1389 1388
1390 void LoadStubCompiler::GenerateLoadInterceptor( 1389 void LoadStubCompiler::GenerateLoadInterceptor(
1391 Register holder_reg, 1390 Register holder_reg,
1392 Handle<JSObject> object, 1391 Handle<Object> object,
1393 Handle<JSObject> interceptor_holder, 1392 Handle<JSObject> interceptor_holder,
1394 LookupResult* lookup, 1393 LookupResult* lookup,
1395 Handle<Name> name) { 1394 Handle<Name> name) {
1396 ASSERT(interceptor_holder->HasNamedInterceptor()); 1395 ASSERT(interceptor_holder->HasNamedInterceptor());
1397 ASSERT(!interceptor_holder->GetNamedInterceptor()->getter()->IsUndefined()); 1396 ASSERT(!interceptor_holder->GetNamedInterceptor()->getter()->IsUndefined());
1398 1397
1399 // So far the most popular follow ups for interceptor loads are FIELD 1398 // So far the most popular follow ups for interceptor loads are FIELD
1400 // and CALLBACKS, so inline only them, other cases may be added 1399 // and CALLBACKS, so inline only them, other cases may be added
1401 // later. 1400 // later.
1402 bool compile_followup_inline = false; 1401 bool compile_followup_inline = false;
(...skipping 219 matching lines...) Expand 10 before | Expand all | Expand 10 after
1622 CheckPrototypes(Handle<JSObject>::cast(object), rdx, holder, rbx, rax, rdi, 1621 CheckPrototypes(Handle<JSObject>::cast(object), rdx, holder, rbx, rax, rdi,
1623 name, &miss); 1622 name, &miss);
1624 } else { 1623 } else {
1625 ASSERT(cell->value() == *function); 1624 ASSERT(cell->value() == *function);
1626 GenerateGlobalReceiverCheck(Handle<JSObject>::cast(object), holder, name, 1625 GenerateGlobalReceiverCheck(Handle<JSObject>::cast(object), holder, name,
1627 &miss); 1626 &miss);
1628 GenerateLoadFunctionFromCell(cell, function, &miss); 1627 GenerateLoadFunctionFromCell(cell, function, &miss);
1629 } 1628 }
1630 1629
1631 Handle<AllocationSite> site = isolate()->factory()->NewAllocationSite(); 1630 Handle<AllocationSite> site = isolate()->factory()->NewAllocationSite();
1632 site->set_transition_info(Smi::FromInt(GetInitialFastElementsKind())); 1631 site->SetElementsKind(GetInitialFastElementsKind());
1633 Handle<Cell> site_feedback_cell = isolate()->factory()->NewCell(site); 1632 Handle<Cell> site_feedback_cell = isolate()->factory()->NewCell(site);
1634 __ movq(rax, Immediate(argc)); 1633 __ movq(rax, Immediate(argc));
1635 __ Move(rbx, site_feedback_cell); 1634 __ Move(rbx, site_feedback_cell);
1636 __ Move(rdi, function); 1635 __ Move(rdi, function);
1637 1636
1638 ArrayConstructorStub stub(isolate()); 1637 ArrayConstructorStub stub(isolate());
1639 __ TailCallStub(&stub); 1638 __ TailCallStub(&stub);
1640 1639
1641 __ bind(&miss); 1640 __ bind(&miss);
1642 GenerateMissBranch(); 1641 GenerateMissBranch();
(...skipping 11 matching lines...) Expand all
1654 Handle<String> name, 1653 Handle<String> name,
1655 Code::StubType type) { 1654 Code::StubType type) {
1656 // ----------- S t a t e ------------- 1655 // ----------- S t a t e -------------
1657 // -- rcx : name 1656 // -- rcx : name
1658 // -- rsp[0] : return address 1657 // -- rsp[0] : return address
1659 // -- rsp[(argc - n) * 8] : arg[n] (zero-based) 1658 // -- rsp[(argc - n) * 8] : arg[n] (zero-based)
1660 // -- ... 1659 // -- ...
1661 // -- rsp[(argc + 1) * 8] : receiver 1660 // -- rsp[(argc + 1) * 8] : receiver
1662 // ----------------------------------- 1661 // -----------------------------------
1663 1662
1664 // If object is not an array, bail out to regular call. 1663 // If object is not an array or is observed, bail out to regular call.
1665 if (!object->IsJSArray() || !cell.is_null()) return Handle<Code>::null(); 1664 if (!object->IsJSArray() ||
1665 !cell.is_null() ||
1666 Handle<JSArray>::cast(object)->map()->is_observed()) {
1667 return Handle<Code>::null();
1668 }
1666 1669
1667 Label miss; 1670 Label miss;
1668 GenerateNameCheck(name, &miss); 1671 GenerateNameCheck(name, &miss);
1669 1672
1670 const int argc = arguments().immediate(); 1673 const int argc = arguments().immediate();
1671 StackArgumentsAccessor args(rsp, argc); 1674 StackArgumentsAccessor args(rsp, argc);
1672 __ movq(rdx, args.GetReceiverOperand()); 1675 __ movq(rdx, args.GetReceiverOperand());
1673 1676
1674 // Check that the receiver isn't a smi. 1677 // Check that the receiver isn't a smi.
1675 __ JumpIfSmi(rdx, &miss); 1678 __ JumpIfSmi(rdx, &miss);
(...skipping 229 matching lines...) Expand 10 before | Expand all | Expand 10 after
1905 Handle<String> name, 1908 Handle<String> name,
1906 Code::StubType type) { 1909 Code::StubType type) {
1907 // ----------- S t a t e ------------- 1910 // ----------- S t a t e -------------
1908 // -- rcx : name 1911 // -- rcx : name
1909 // -- rsp[0] : return address 1912 // -- rsp[0] : return address
1910 // -- rsp[(argc - n) * 8] : arg[n] (zero-based) 1913 // -- rsp[(argc - n) * 8] : arg[n] (zero-based)
1911 // -- ... 1914 // -- ...
1912 // -- rsp[(argc + 1) * 8] : receiver 1915 // -- rsp[(argc + 1) * 8] : receiver
1913 // ----------------------------------- 1916 // -----------------------------------
1914 1917
1915 // If object is not an array, bail out to regular call. 1918 // If object is not an array or is observed, bail out to regular call.
1916 if (!object->IsJSArray() || !cell.is_null()) return Handle<Code>::null(); 1919 if (!object->IsJSArray() ||
1920 !cell.is_null() ||
1921 Handle<JSArray>::cast(object)->map()->is_observed()) {
1922 return Handle<Code>::null();
1923 }
1917 1924
1918 Label miss, return_undefined, call_builtin; 1925 Label miss, return_undefined, call_builtin;
1919 GenerateNameCheck(name, &miss); 1926 GenerateNameCheck(name, &miss);
1920 1927
1921 const int argc = arguments().immediate(); 1928 const int argc = arguments().immediate();
1922 StackArgumentsAccessor args(rsp, argc); 1929 StackArgumentsAccessor args(rsp, argc);
1923 __ movq(rdx, args.GetReceiverOperand()); 1930 __ movq(rdx, args.GetReceiverOperand());
1924 1931
1925 // Check that the receiver isn't a smi. 1932 // Check that the receiver isn't a smi.
1926 __ JumpIfSmi(rdx, &miss); 1933 __ JumpIfSmi(rdx, &miss);
(...skipping 573 matching lines...) Expand 10 before | Expand all | Expand 10 after
2500 __ addq(rsp, Immediate(kFastApiCallArguments * kPointerSize)); 2507 __ addq(rsp, Immediate(kFastApiCallArguments * kPointerSize));
2501 2508
2502 __ bind(&miss_before_stack_reserved); 2509 __ bind(&miss_before_stack_reserved);
2503 GenerateMissBranch(); 2510 GenerateMissBranch();
2504 2511
2505 // Return the generated code. 2512 // Return the generated code.
2506 return GetCode(function); 2513 return GetCode(function);
2507 } 2514 }
2508 2515
2509 2516
2517 void StubCompiler::GenerateBooleanCheck(Register object, Label* miss) {
2518 Label success;
2519 // Check that the object is a boolean.
2520 __ CompareRoot(object, Heap::kTrueValueRootIndex);
2521 __ j(equal, &success);
2522 __ CompareRoot(object, Heap::kFalseValueRootIndex);
2523 __ j(not_equal, miss);
2524 __ bind(&success);
2525 }
2526
2527
2510 void CallStubCompiler::CompileHandlerFrontend(Handle<Object> object, 2528 void CallStubCompiler::CompileHandlerFrontend(Handle<Object> object,
2511 Handle<JSObject> holder, 2529 Handle<JSObject> holder,
2512 Handle<Name> name, 2530 Handle<Name> name,
2513 CheckType check, 2531 CheckType check) {
2514 Label* success) {
2515 // ----------- S t a t e ------------- 2532 // ----------- S t a t e -------------
2516 // rcx : function name 2533 // rcx : function name
2517 // rsp[0] : return address 2534 // rsp[0] : return address
2518 // rsp[8] : argument argc 2535 // rsp[8] : argument argc
2519 // rsp[16] : argument argc - 1 2536 // rsp[16] : argument argc - 1
2520 // ... 2537 // ...
2521 // rsp[argc * 8] : argument 1 2538 // rsp[argc * 8] : argument 1
2522 // rsp[(argc + 1) * 8] : argument 0 = receiver 2539 // rsp[(argc + 1) * 8] : argument 0 = receiver
2523 // ----------------------------------- 2540 // -----------------------------------
2524 Label miss; 2541 Label miss;
(...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after
2586 __ bind(&fast); 2603 __ bind(&fast);
2587 // Check that the maps starting from the prototype haven't changed. 2604 // Check that the maps starting from the prototype haven't changed.
2588 GenerateDirectLoadGlobalFunctionPrototype( 2605 GenerateDirectLoadGlobalFunctionPrototype(
2589 masm(), Context::NUMBER_FUNCTION_INDEX, rax, &miss); 2606 masm(), Context::NUMBER_FUNCTION_INDEX, rax, &miss);
2590 CheckPrototypes( 2607 CheckPrototypes(
2591 Handle<JSObject>(JSObject::cast(object->GetPrototype(isolate()))), 2608 Handle<JSObject>(JSObject::cast(object->GetPrototype(isolate()))),
2592 rax, holder, rbx, rdx, rdi, name, &miss); 2609 rax, holder, rbx, rdx, rdi, name, &miss);
2593 break; 2610 break;
2594 } 2611 }
2595 case BOOLEAN_CHECK: { 2612 case BOOLEAN_CHECK: {
2596 Label fast; 2613 GenerateBooleanCheck(rdx, &miss);
2597 // Check that the object is a boolean.
2598 __ CompareRoot(rdx, Heap::kTrueValueRootIndex);
2599 __ j(equal, &fast);
2600 __ CompareRoot(rdx, Heap::kFalseValueRootIndex);
2601 __ j(not_equal, &miss);
2602 __ bind(&fast);
2603 // Check that the maps starting from the prototype haven't changed. 2614 // Check that the maps starting from the prototype haven't changed.
2604 GenerateDirectLoadGlobalFunctionPrototype( 2615 GenerateDirectLoadGlobalFunctionPrototype(
2605 masm(), Context::BOOLEAN_FUNCTION_INDEX, rax, &miss); 2616 masm(), Context::BOOLEAN_FUNCTION_INDEX, rax, &miss);
2606 CheckPrototypes( 2617 CheckPrototypes(
2607 Handle<JSObject>(JSObject::cast(object->GetPrototype(isolate()))), 2618 Handle<JSObject>(JSObject::cast(object->GetPrototype(isolate()))),
2608 rax, holder, rbx, rdx, rdi, name, &miss); 2619 rax, holder, rbx, rdx, rdi, name, &miss);
2609 break; 2620 break;
2610 } 2621 }
2611 } 2622 }
2612 2623
2613 __ jmp(success); 2624 Label success;
2625 __ jmp(&success);
2614 2626
2615 // Handle call cache miss. 2627 // Handle call cache miss.
2616 __ bind(&miss); 2628 __ bind(&miss);
2617 GenerateMissBranch(); 2629 GenerateMissBranch();
2630
2631 __ bind(&success);
2618 } 2632 }
2619 2633
2620 2634
2621 void CallStubCompiler::CompileHandlerBackend(Handle<JSFunction> function) { 2635 void CallStubCompiler::CompileHandlerBackend(Handle<JSFunction> function) {
2622 CallKind call_kind = CallICBase::Contextual::decode(extra_state_) 2636 CallKind call_kind = CallICBase::Contextual::decode(extra_state_)
2623 ? CALL_AS_FUNCTION 2637 ? CALL_AS_FUNCTION
2624 : CALL_AS_METHOD; 2638 : CALL_AS_METHOD;
2625 ParameterCount expected(function); 2639 ParameterCount expected(function);
2626 __ InvokeFunction(function, expected, arguments(), 2640 __ InvokeFunction(function, expected, arguments(),
2627 JUMP_FUNCTION, NullCallWrapper(), call_kind); 2641 JUMP_FUNCTION, NullCallWrapper(), call_kind);
2628 } 2642 }
2629 2643
2630 2644
2631 Handle<Code> CallStubCompiler::CompileCallConstant( 2645 Handle<Code> CallStubCompiler::CompileCallConstant(
2632 Handle<Object> object, 2646 Handle<Object> object,
2633 Handle<JSObject> holder, 2647 Handle<JSObject> holder,
2634 Handle<Name> name, 2648 Handle<Name> name,
2635 CheckType check, 2649 CheckType check,
2636 Handle<JSFunction> function) { 2650 Handle<JSFunction> function) {
2637 if (HasCustomCallGenerator(function)) { 2651 if (HasCustomCallGenerator(function)) {
2638 Handle<Code> code = CompileCustomCall(object, holder, 2652 Handle<Code> code = CompileCustomCall(object, holder,
2639 Handle<PropertyCell>::null(), 2653 Handle<PropertyCell>::null(),
2640 function, Handle<String>::cast(name), 2654 function, Handle<String>::cast(name),
2641 Code::CONSTANT); 2655 Code::CONSTANT);
2642 // A null handle means bail out to the regular compiler code below. 2656 // A null handle means bail out to the regular compiler code below.
2643 if (!code.is_null()) return code; 2657 if (!code.is_null()) return code;
2644 } 2658 }
2645 2659
2646 Label success; 2660 CompileHandlerFrontend(object, holder, name, check);
2647
2648 CompileHandlerFrontend(object, holder, name, check, &success);
2649 __ bind(&success);
2650 CompileHandlerBackend(function); 2661 CompileHandlerBackend(function);
2651 2662
2652 // Return the generated code. 2663 // Return the generated code.
2653 return GetCode(function); 2664 return GetCode(function);
2654 } 2665 }
2655 2666
2656 2667
2657 Handle<Code> CallStubCompiler::CompileCallInterceptor(Handle<JSObject> object, 2668 Handle<Code> CallStubCompiler::CompileCallInterceptor(Handle<JSObject> object,
2658 Handle<JSObject> holder, 2669 Handle<JSObject> holder,
2659 Handle<Name> name) { 2670 Handle<Name> name) {
(...skipping 115 matching lines...) Expand 10 before | Expand all | Expand 10 after
2775 // Return the generated code. 2786 // Return the generated code.
2776 return GetCode(Code::NORMAL, name); 2787 return GetCode(Code::NORMAL, name);
2777 } 2788 }
2778 2789
2779 2790
2780 Handle<Code> StoreStubCompiler::CompileStoreCallback( 2791 Handle<Code> StoreStubCompiler::CompileStoreCallback(
2781 Handle<JSObject> object, 2792 Handle<JSObject> object,
2782 Handle<JSObject> holder, 2793 Handle<JSObject> holder,
2783 Handle<Name> name, 2794 Handle<Name> name,
2784 Handle<ExecutableAccessorInfo> callback) { 2795 Handle<ExecutableAccessorInfo> callback) {
2785 Label success; 2796 HandlerFrontend(object, receiver(), holder, name);
2786 HandlerFrontend(object, receiver(), holder, name, &success);
2787 __ bind(&success);
2788 2797
2789 __ PopReturnAddressTo(scratch1()); 2798 __ PopReturnAddressTo(scratch1());
2790 __ push(receiver()); 2799 __ push(receiver());
2791 __ Push(callback); // callback info 2800 __ Push(callback); // callback info
2792 __ Push(name); 2801 __ Push(name);
2793 __ push(value()); 2802 __ push(value());
2794 __ PushReturnAddressFrom(scratch1()); 2803 __ PushReturnAddressFrom(scratch1());
2795 2804
2796 // Do tail-call to the runtime system. 2805 // Do tail-call to the runtime system.
2797 ExternalReference store_callback_property = 2806 ExternalReference store_callback_property =
2798 ExternalReference(IC_Utility(IC::kStoreCallbackProperty), isolate()); 2807 ExternalReference(IC_Utility(IC::kStoreCallbackProperty), isolate());
2799 __ TailCallExternalReference(store_callback_property, 4, 1); 2808 __ TailCallExternalReference(store_callback_property, 4, 1);
2800 2809
2801 // Return the generated code. 2810 // Return the generated code.
2802 return GetCode(kind(), Code::CALLBACKS, name); 2811 return GetCode(kind(), Code::CALLBACKS, name);
2803 } 2812 }
2804 2813
2805 2814
2806 Handle<Code> StoreStubCompiler::CompileStoreCallback( 2815 Handle<Code> StoreStubCompiler::CompileStoreCallback(
2807 Handle<JSObject> object, 2816 Handle<JSObject> object,
2808 Handle<JSObject> holder, 2817 Handle<JSObject> holder,
2809 Handle<Name> name, 2818 Handle<Name> name,
2810 const CallOptimization& call_optimization) { 2819 const CallOptimization& call_optimization) {
2811 Label success; 2820 HandlerFrontend(object, receiver(), holder, name);
2812 HandlerFrontend(object, receiver(), holder, name, &success);
2813 __ bind(&success);
2814 2821
2815 Register values[] = { value() }; 2822 Register values[] = { value() };
2816 GenerateFastApiCall( 2823 GenerateFastApiCall(
2817 masm(), call_optimization, receiver(), scratch3(), 1, values); 2824 masm(), call_optimization, receiver(), scratch3(), 1, values);
2818 2825
2819 // Return the generated code. 2826 // Return the generated code.
2820 return GetCode(kind(), Code::CALLBACKS, name); 2827 return GetCode(kind(), Code::CALLBACKS, name);
2821 } 2828 }
2822 2829
2823 2830
(...skipping 93 matching lines...) Expand 10 before | Expand all | Expand 10 after
2917 2924
2918 TailCallBuiltin(masm(), MissBuiltin(kind())); 2925 TailCallBuiltin(masm(), MissBuiltin(kind()));
2919 2926
2920 // Return the generated code. 2927 // Return the generated code.
2921 return GetICCode( 2928 return GetICCode(
2922 kind(), Code::NORMAL, factory()->empty_string(), POLYMORPHIC); 2929 kind(), Code::NORMAL, factory()->empty_string(), POLYMORPHIC);
2923 } 2930 }
2924 2931
2925 2932
2926 Handle<Code> LoadStubCompiler::CompileLoadNonexistent( 2933 Handle<Code> LoadStubCompiler::CompileLoadNonexistent(
2927 Handle<JSObject> object, 2934 Handle<Object> object,
2928 Handle<JSObject> last, 2935 Handle<JSObject> last,
2929 Handle<Name> name, 2936 Handle<Name> name,
2930 Handle<JSGlobalObject> global) { 2937 Handle<JSGlobalObject> global) {
2931 Label success; 2938 NonexistentHandlerFrontend(object, last, name, global);
2932 2939
2933 NonexistentHandlerFrontend(object, last, name, &success, global);
2934
2935 __ bind(&success);
2936 // Return undefined if maps of the full prototype chain are still the 2940 // Return undefined if maps of the full prototype chain are still the
2937 // same and no global property with this name contains a value. 2941 // same and no global property with this name contains a value.
2938 __ LoadRoot(rax, Heap::kUndefinedValueRootIndex); 2942 __ LoadRoot(rax, Heap::kUndefinedValueRootIndex);
2939 __ ret(0); 2943 __ ret(0);
2940 2944
2941 // Return the generated code. 2945 // Return the generated code.
2942 return GetCode(kind(), Code::NONEXISTENT, name); 2946 return GetCode(kind(), Code::NONEXISTENT, name);
2943 } 2947 }
2944 2948
2945 2949
(...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after
3020 } 3024 }
3021 __ ret(0); 3025 __ ret(0);
3022 } 3026 }
3023 3027
3024 3028
3025 #undef __ 3029 #undef __
3026 #define __ ACCESS_MASM(masm()) 3030 #define __ ACCESS_MASM(masm())
3027 3031
3028 3032
3029 Handle<Code> LoadStubCompiler::CompileLoadGlobal( 3033 Handle<Code> LoadStubCompiler::CompileLoadGlobal(
3030 Handle<JSObject> object, 3034 Handle<Object> object,
3031 Handle<GlobalObject> global, 3035 Handle<GlobalObject> global,
3032 Handle<PropertyCell> cell, 3036 Handle<PropertyCell> cell,
3033 Handle<Name> name, 3037 Handle<Name> name,
3034 bool is_dont_delete) { 3038 bool is_dont_delete) {
3035 Label success, miss; 3039 Label miss;
3036 // TODO(verwaest): Directly store to rax. Currently we cannot do this, since 3040 // TODO(verwaest): Directly store to rax. Currently we cannot do this, since
3037 // rax is used as receiver(), which we would otherwise clobber before a 3041 // rax is used as receiver(), which we would otherwise clobber before a
3038 // potential miss. 3042 // potential miss.
3039 HandlerFrontendHeader(object, receiver(), global, name, &miss); 3043 HandlerFrontendHeader(object, receiver(), global, name, &miss);
3040 3044
3041 // Get the value from the cell. 3045 // Get the value from the cell.
3042 __ Move(rbx, cell); 3046 __ Move(rbx, cell);
3043 __ movq(rbx, FieldOperand(rbx, PropertyCell::kValueOffset)); 3047 __ movq(rbx, FieldOperand(rbx, PropertyCell::kValueOffset));
3044 3048
3045 // Check for deleted property if property can actually be deleted. 3049 // Check for deleted property if property can actually be deleted.
3046 if (!is_dont_delete) { 3050 if (!is_dont_delete) {
3047 __ CompareRoot(rbx, Heap::kTheHoleValueRootIndex); 3051 __ CompareRoot(rbx, Heap::kTheHoleValueRootIndex);
3048 __ j(equal, &miss); 3052 __ j(equal, &miss);
3049 } else if (FLAG_debug_code) { 3053 } else if (FLAG_debug_code) {
3050 __ CompareRoot(rbx, Heap::kTheHoleValueRootIndex); 3054 __ CompareRoot(rbx, Heap::kTheHoleValueRootIndex);
3051 __ Check(not_equal, kDontDeleteCellsCannotContainTheHole); 3055 __ Check(not_equal, kDontDeleteCellsCannotContainTheHole);
3052 } 3056 }
3053 3057
3054 HandlerFrontendFooter(name, &success, &miss); 3058 HandlerFrontendFooter(name, &miss);
3055 __ bind(&success);
3056 3059
3057 Counters* counters = isolate()->counters(); 3060 Counters* counters = isolate()->counters();
3058 __ IncrementCounter(counters->named_load_global_stub(), 1); 3061 __ IncrementCounter(counters->named_load_global_stub(), 1);
3059 __ movq(rax, rbx); 3062 __ movq(rax, rbx);
3060 __ ret(0); 3063 __ ret(0);
3061 3064
3062 // Return the generated code. 3065 // Return the generated code.
3063 return GetCode(kind(), Code::NORMAL, name); 3066 return GetCode(kind(), Code::NORMAL, name);
3064 } 3067 }
3065 3068
3066 3069
3067 Handle<Code> BaseLoadStoreStubCompiler::CompilePolymorphicIC( 3070 Handle<Code> BaseLoadStoreStubCompiler::CompilePolymorphicIC(
3068 MapHandleList* receiver_maps, 3071 MapHandleList* receiver_maps,
3069 CodeHandleList* handlers, 3072 CodeHandleList* handlers,
3070 Handle<Name> name, 3073 Handle<Name> name,
3071 Code::StubType type, 3074 Code::StubType type,
3072 IcCheckType check) { 3075 IcCheckType check) {
3073 Label miss; 3076 Label miss;
3074 3077
3075 if (check == PROPERTY) { 3078 if (check == PROPERTY) {
3076 GenerateNameCheck(name, this->name(), &miss); 3079 GenerateNameCheck(name, this->name(), &miss);
3077 } 3080 }
3078 3081
3079 __ JumpIfSmi(receiver(), &miss); 3082 Label number_case;
3083 Label* smi_target = HasHeapNumberMap(receiver_maps) ? &number_case : &miss;
3084 __ JumpIfSmi(receiver(), smi_target);
3085
3080 Register map_reg = scratch1(); 3086 Register map_reg = scratch1();
3081 __ movq(map_reg, FieldOperand(receiver(), HeapObject::kMapOffset)); 3087 __ movq(map_reg, FieldOperand(receiver(), HeapObject::kMapOffset));
3082 int receiver_count = receiver_maps->length(); 3088 int receiver_count = receiver_maps->length();
3083 int number_of_handled_maps = 0; 3089 int number_of_handled_maps = 0;
3090 Handle<Map> heap_number_map = isolate()->factory()->heap_number_map();
3084 for (int current = 0; current < receiver_count; ++current) { 3091 for (int current = 0; current < receiver_count; ++current) {
3085 Handle<Map> map = receiver_maps->at(current); 3092 Handle<Map> map = receiver_maps->at(current);
3086 if (!map->is_deprecated()) { 3093 if (!map->is_deprecated()) {
3087 number_of_handled_maps++; 3094 number_of_handled_maps++;
3088 // Check map and tail call if there's a match 3095 // Check map and tail call if there's a match
3089 __ Cmp(map_reg, receiver_maps->at(current)); 3096 __ Cmp(map_reg, receiver_maps->at(current));
3097 if (map.is_identical_to(heap_number_map)) {
3098 ASSERT(!number_case.is_unused());
3099 __ bind(&number_case);
3100 }
3090 __ j(equal, handlers->at(current), RelocInfo::CODE_TARGET); 3101 __ j(equal, handlers->at(current), RelocInfo::CODE_TARGET);
3091 } 3102 }
3092 } 3103 }
3093 ASSERT(number_of_handled_maps > 0); 3104 ASSERT(number_of_handled_maps > 0);
3094 3105
3095 __ bind(&miss); 3106 __ bind(&miss);
3096 TailCallBuiltin(masm(), MissBuiltin(kind())); 3107 TailCallBuiltin(masm(), MissBuiltin(kind()));
3097 3108
3098 // Return the generated code. 3109 // Return the generated code.
3099 InlineCacheState state = 3110 InlineCacheState state =
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after
3146 // ----------------------------------- 3157 // -----------------------------------
3147 TailCallBuiltin(masm, Builtins::kKeyedLoadIC_MissForceGeneric); 3158 TailCallBuiltin(masm, Builtins::kKeyedLoadIC_MissForceGeneric);
3148 } 3159 }
3149 3160
3150 3161
3151 #undef __ 3162 #undef __
3152 3163
3153 } } // namespace v8::internal 3164 } } // namespace v8::internal
3154 3165
3155 #endif // V8_TARGET_ARCH_X64 3166 #endif // V8_TARGET_ARCH_X64
OLDNEW
« no previous file with comments | « src/x64/macro-assembler-x64.cc ('k') | test/cctest/cctest.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698