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

Side by Side Diff: src/a64/stub-cache-a64.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/a64/macro-assembler-a64.cc ('k') | src/allocation-tracker.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 2013 the V8 project authors. All rights reserved. 1 // Copyright 2013 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 1268 matching lines...) Expand 10 before | Expand all | Expand 10 after
1279 // If we've skipped any global objects, it's not enough to verify that 1279 // If we've skipped any global objects, it's not enough to verify that
1280 // their maps haven't changed. We also need to check that the property 1280 // their maps haven't changed. We also need to check that the property
1281 // cell for the property is still empty. 1281 // cell for the property is still empty.
1282 GenerateCheckPropertyCells(masm(), object, holder, name, scratch1, miss); 1282 GenerateCheckPropertyCells(masm(), object, holder, name, scratch1, miss);
1283 1283
1284 // Return the register containing the holder. 1284 // Return the register containing the holder.
1285 return reg; 1285 return reg;
1286 } 1286 }
1287 1287
1288 1288
1289 void LoadStubCompiler::HandlerFrontendFooter(Handle<Name> name, 1289 void LoadStubCompiler::HandlerFrontendFooter(Handle<Name> name, Label* miss) {
1290 Label* success,
1291 Label* miss) {
1292 if (!miss->is_unused()) { 1290 if (!miss->is_unused()) {
1293 __ B(success); 1291 Label success;
1292 __ B(&success);
1293
1294 __ Bind(miss); 1294 __ Bind(miss);
1295 TailCallBuiltin(masm(), MissBuiltin(kind())); 1295 TailCallBuiltin(masm(), MissBuiltin(kind()));
1296
1297 __ Bind(&success);
1296 } 1298 }
1297 } 1299 }
1298 1300
1299 1301
1300 void StoreStubCompiler::HandlerFrontendFooter(Handle<Name> name, 1302 void StoreStubCompiler::HandlerFrontendFooter(Handle<Name> name, Label* miss) {
1301 Label* success,
1302 Label* miss) {
1303 if (!miss->is_unused()) { 1303 if (!miss->is_unused()) {
1304 __ B(success); 1304 Label success;
1305 __ B(&success);
1306
1305 GenerateRestoreName(masm(), miss, name); 1307 GenerateRestoreName(masm(), miss, name);
1306 TailCallBuiltin(masm(), MissBuiltin(kind())); 1308 TailCallBuiltin(masm(), MissBuiltin(kind()));
1309
1310 __ Bind(&success);
1307 } 1311 }
1308 } 1312 }
1309 1313
1310 1314
1311 Register LoadStubCompiler::CallbackHandlerFrontend(Handle<JSObject> object, 1315 Register LoadStubCompiler::CallbackHandlerFrontend(Handle<Object> object,
1312 Register object_reg, 1316 Register object_reg,
1313 Handle<JSObject> holder, 1317 Handle<JSObject> holder,
1314 Handle<Name> name, 1318 Handle<Name> name,
1315 Label* success,
1316 Handle<Object> callback) { 1319 Handle<Object> callback) {
1317 Label miss; 1320 Label miss;
1318 1321
1319 Register reg = HandlerFrontendHeader(object, object_reg, holder, name, &miss); 1322 Register reg = HandlerFrontendHeader(object, object_reg, holder, name, &miss);
1320 1323
1321 // TODO(jbramely): HandlerFrontendHeader returns its result in scratch1(), so 1324 // TODO(jbramely): HandlerFrontendHeader returns its result in scratch1(), so
1322 // we can't use it below, but that isn't very obvious. Is there a better way 1325 // we can't use it below, but that isn't very obvious. Is there a better way
1323 // of handling this? 1326 // of handling this?
1324 1327
1325 if (!holder->HasFastProperties() && !holder->IsJSGlobalObject()) { 1328 if (!holder->HasFastProperties() && !holder->IsJSGlobalObject()) {
(...skipping 18 matching lines...) Expand all
1344 // pointer into the dictionary. Check that the value is the callback. 1347 // pointer into the dictionary. Check that the value is the callback.
1345 Register pointer = scratch3(); 1348 Register pointer = scratch3();
1346 const int kElementsStartOffset = NameDictionary::kHeaderSize + 1349 const int kElementsStartOffset = NameDictionary::kHeaderSize +
1347 NameDictionary::kElementsStartIndex * kPointerSize; 1350 NameDictionary::kElementsStartIndex * kPointerSize;
1348 const int kValueOffset = kElementsStartOffset + kPointerSize; 1351 const int kValueOffset = kElementsStartOffset + kPointerSize;
1349 __ Ldr(scratch2(), FieldMemOperand(pointer, kValueOffset)); 1352 __ Ldr(scratch2(), FieldMemOperand(pointer, kValueOffset));
1350 __ Cmp(scratch2(), Operand(callback)); 1353 __ Cmp(scratch2(), Operand(callback));
1351 __ B(ne, &miss); 1354 __ B(ne, &miss);
1352 } 1355 }
1353 1356
1354 HandlerFrontendFooter(name, success, &miss); 1357 HandlerFrontendFooter(name, &miss);
1355 return reg; 1358 return reg;
1356 } 1359 }
1357 1360
1358 1361
1359 void LoadStubCompiler::GenerateLoadField(Register reg, 1362 void LoadStubCompiler::GenerateLoadField(Register reg,
1360 Handle<JSObject> holder, 1363 Handle<JSObject> holder,
1361 PropertyIndex field, 1364 PropertyIndex field,
1362 Representation representation) { 1365 Representation representation) {
1363 __ Mov(receiver(), reg); 1366 __ Mov(receiver(), reg);
1364 if (kind() == Code::LOAD_IC) { 1367 if (kind() == Code::LOAD_IC) {
(...skipping 119 matching lines...) Expand 10 before | Expand all | Expand 10 after
1484 x2, 1487 x2,
1485 kStackUnwindSpace, 1488 kStackUnwindSpace,
1486 spill_offset, 1489 spill_offset,
1487 MemOperand(fp, 6 * kPointerSize), 1490 MemOperand(fp, 6 * kPointerSize),
1488 NULL); 1491 NULL);
1489 } 1492 }
1490 1493
1491 1494
1492 void LoadStubCompiler::GenerateLoadInterceptor( 1495 void LoadStubCompiler::GenerateLoadInterceptor(
1493 Register holder_reg, 1496 Register holder_reg,
1494 Handle<JSObject> object, 1497 Handle<Object> object,
1495 Handle<JSObject> interceptor_holder, 1498 Handle<JSObject> interceptor_holder,
1496 LookupResult* lookup, 1499 LookupResult* lookup,
1497 Handle<Name> name) { 1500 Handle<Name> name) {
1498 ASSERT(!AreAliased(receiver(), this->name(), 1501 ASSERT(!AreAliased(receiver(), this->name(),
1499 scratch1(), scratch2(), scratch3())); 1502 scratch1(), scratch2(), scratch3()));
1500 ASSERT(interceptor_holder->HasNamedInterceptor()); 1503 ASSERT(interceptor_holder->HasNamedInterceptor());
1501 ASSERT(!interceptor_holder->GetNamedInterceptor()->getter()->IsUndefined()); 1504 ASSERT(!interceptor_holder->GetNamedInterceptor()->getter()->IsUndefined());
1502 1505
1503 // So far the most popular follow ups for interceptor loads are FIELD 1506 // So far the most popular follow ups for interceptor loads are FIELD
1504 // and CALLBACKS, so inline only them, other cases may be added later. 1507 // and CALLBACKS, so inline only them, other cases may be added later.
(...skipping 214 matching lines...) Expand 10 before | Expand all | Expand 10 after
1719 CheckPrototypes(Handle<JSObject>::cast(object), receiver, holder, x3, x0, 1722 CheckPrototypes(Handle<JSObject>::cast(object), receiver, holder, x3, x0,
1720 x4, name, &miss); 1723 x4, name, &miss);
1721 } else { 1724 } else {
1722 ASSERT(cell->value() == *function); 1725 ASSERT(cell->value() == *function);
1723 GenerateGlobalReceiverCheck(Handle<JSObject>::cast(object), holder, name, 1726 GenerateGlobalReceiverCheck(Handle<JSObject>::cast(object), holder, name,
1724 &miss); 1727 &miss);
1725 GenerateLoadFunctionFromCell(cell, function, &miss); 1728 GenerateLoadFunctionFromCell(cell, function, &miss);
1726 } 1729 }
1727 1730
1728 Handle<AllocationSite> site = isolate()->factory()->NewAllocationSite(); 1731 Handle<AllocationSite> site = isolate()->factory()->NewAllocationSite();
1729 site->set_transition_info(Smi::FromInt(GetInitialFastElementsKind())); 1732 site->SetElementsKind(GetInitialFastElementsKind());
1730 Handle<Cell> site_feedback_cell = isolate()->factory()->NewCell(site); 1733 Handle<Cell> site_feedback_cell = isolate()->factory()->NewCell(site);
1731 __ Mov(x0, argc); 1734 __ Mov(x0, argc);
1732 __ Mov(x1, Operand(function)); 1735 __ Mov(x1, Operand(function));
1733 __ Mov(x2, Operand(site_feedback_cell)); 1736 __ Mov(x2, Operand(site_feedback_cell));
1734 1737
1735 ArrayConstructorStub stub(isolate()); 1738 ArrayConstructorStub stub(isolate());
1736 __ TailCallStub(&stub); 1739 __ TailCallStub(&stub);
1737 1740
1738 __ Bind(&miss); 1741 __ Bind(&miss);
1739 GenerateMissBranch(); 1742 GenerateMissBranch();
(...skipping 11 matching lines...) Expand all
1751 Handle<String> name, 1754 Handle<String> name,
1752 Code::StubType type) { 1755 Code::StubType type) {
1753 // ----------- S t a t e ------------- 1756 // ----------- S t a t e -------------
1754 // -- x2 : name (Must be preserved on miss.) 1757 // -- x2 : name (Must be preserved on miss.)
1755 // -- lr : return address 1758 // -- lr : return address
1756 // -- sp[(argc - n - 1) * 8] : arg[n] (zero-based) 1759 // -- sp[(argc - n - 1) * 8] : arg[n] (zero-based)
1757 // -- ... 1760 // -- ...
1758 // -- sp[argc * 8] : receiver 1761 // -- sp[argc * 8] : receiver
1759 // ----------------------------------- 1762 // -----------------------------------
1760 1763
1761 // If object is not an array, bail out to regular call. 1764 // If object is not an array or is observed, bail out to regular call.
1762 if (!object->IsJSArray() || !cell.is_null()) return Handle<Code>::null(); 1765 if (!object->IsJSArray() ||
1766 !cell.is_null() ||
1767 Handle<JSArray>::cast(object)->map()->is_observed()) {
1768 return Handle<Code>::null();
1769 }
1763 1770
1764 Label miss; 1771 Label miss;
1765 Register result = x0; 1772 Register result = x0;
1766 const int argc = arguments().immediate(); 1773 const int argc = arguments().immediate();
1767 1774
1768 GenerateNameCheck(name, &miss); 1775 GenerateNameCheck(name, &miss);
1769 1776
1770 // Get the receiver from the stack 1777 // Get the receiver from the stack
1771 Register receiver = x1; 1778 Register receiver = x1;
1772 __ Peek(receiver, argc * kPointerSize); 1779 __ Peek(receiver, argc * kPointerSize);
(...skipping 248 matching lines...) Expand 10 before | Expand all | Expand 10 after
2021 Handle<String> name, 2028 Handle<String> name,
2022 Code::StubType type) { 2029 Code::StubType type) {
2023 // ----------- S t a t e ------------- 2030 // ----------- S t a t e -------------
2024 // -- x2 : name 2031 // -- x2 : name
2025 // -- lr : return address 2032 // -- lr : return address
2026 // -- sp[(argc - n - 1) * 8] : arg[n] (zero-based) 2033 // -- sp[(argc - n - 1) * 8] : arg[n] (zero-based)
2027 // -- ... 2034 // -- ...
2028 // -- sp[argc * 8] : receiver 2035 // -- sp[argc * 8] : receiver
2029 // ----------------------------------- 2036 // -----------------------------------
2030 2037
2031 // If object is not an array, bail out to regular call. 2038 // If object is not an array or is observed, bail out to regular call.
2032 if (!object->IsJSArray() || !cell.is_null()) return Handle<Code>::null(); 2039 if (!object->IsJSArray() ||
2040 !cell.is_null() ||
2041 Handle<JSArray>::cast(object)->map()->is_observed()) {
2042 return Handle<Code>::null();
2043 }
2033 2044
2034 const int argc = arguments().immediate(); 2045 const int argc = arguments().immediate();
2035 Register result = x0; 2046 Register result = x0;
2036 Label miss, return_undefined, call_builtin; 2047 Label miss, return_undefined, call_builtin;
2037 2048
2038 GenerateNameCheck(name, &miss); 2049 GenerateNameCheck(name, &miss);
2039 2050
2040 // Get the receiver from the stack 2051 // Get the receiver from the stack
2041 Register receiver = x1; 2052 Register receiver = x1;
2042 __ Peek(receiver, argc * kPointerSize); 2053 __ Peek(receiver, argc * kPointerSize);
(...skipping 548 matching lines...) Expand 10 before | Expand all | Expand 10 after
2591 FreeSpaceForFastApiCall(masm()); 2602 FreeSpaceForFastApiCall(masm());
2592 2603
2593 __ Bind(&miss_before_stack_reserved); 2604 __ Bind(&miss_before_stack_reserved);
2594 GenerateMissBranch(); 2605 GenerateMissBranch();
2595 2606
2596 // Return the generated code. 2607 // Return the generated code.
2597 return GetCode(function); 2608 return GetCode(function);
2598 } 2609 }
2599 2610
2600 2611
2612 void StubCompiler::GenerateBooleanCheck(Register object, Label* miss) {
2613 Label success;
2614 // Check that the object is a boolean.
2615 // TODO(all): Optimize this like LCodeGen::DoDeferredTaggedToI.
2616 __ JumpIfRoot(object, Heap::kTrueValueRootIndex, &success);
2617 __ JumpIfNotRoot(object, Heap::kFalseValueRootIndex, miss);
2618 __ Bind(&success);
2619 }
2620
2621
2601 void CallStubCompiler::CompileHandlerFrontend(Handle<Object> object, 2622 void CallStubCompiler::CompileHandlerFrontend(Handle<Object> object,
2602 Handle<JSObject> holder, 2623 Handle<JSObject> holder,
2603 Handle<Name> name, 2624 Handle<Name> name,
2604 CheckType check, 2625 CheckType check) {
2605 Label* success) {
2606 // ----------- S t a t e ------------- 2626 // ----------- S t a t e -------------
2607 // -- x2 : name 2627 // -- x2 : name
2608 // -- lr : return address 2628 // -- lr : return address
2609 // ----------------------------------- 2629 // -----------------------------------
2610 Label miss; 2630 Label miss;
2611 GenerateNameCheck(name, &miss); 2631 GenerateNameCheck(name, &miss);
2612 2632
2613 // Get the receiver from the stack. 2633 // Get the receiver from the stack.
2614 const int argc = arguments().immediate(); 2634 const int argc = arguments().immediate();
2615 Register receiver = x1; 2635 Register receiver = x1;
(...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after
2674 // Check that the maps starting from the prototype haven't changed. 2694 // Check that the maps starting from the prototype haven't changed.
2675 Register prototype = x0; 2695 Register prototype = x0;
2676 GenerateDirectLoadGlobalFunctionPrototype( 2696 GenerateDirectLoadGlobalFunctionPrototype(
2677 masm(), Context::NUMBER_FUNCTION_INDEX, prototype, &miss); 2697 masm(), Context::NUMBER_FUNCTION_INDEX, prototype, &miss);
2678 CheckPrototypes( 2698 CheckPrototypes(
2679 Handle<JSObject>(JSObject::cast(object->GetPrototype(isolate()))), 2699 Handle<JSObject>(JSObject::cast(object->GetPrototype(isolate()))),
2680 prototype, holder, x3, x1, x4, name, &miss); 2700 prototype, holder, x3, x1, x4, name, &miss);
2681 break; 2701 break;
2682 } 2702 }
2683 case BOOLEAN_CHECK: { 2703 case BOOLEAN_CHECK: {
2684 Label fast; 2704 GenerateBooleanCheck(receiver, &miss);
2685 // Check that the object is a boolean.
2686 __ JumpIfRoot(receiver, Heap::kTrueValueRootIndex, &fast);
2687 __ JumpIfNotRoot(receiver, Heap::kFalseValueRootIndex, &miss);
2688 2705
2689 __ Bind(&fast);
2690 // Check that the maps starting from the prototype haven't changed. 2706 // Check that the maps starting from the prototype haven't changed.
2691 Register prototype = x0; 2707 Register prototype = x0;
2692 GenerateDirectLoadGlobalFunctionPrototype( 2708 GenerateDirectLoadGlobalFunctionPrototype(
2693 masm(), Context::BOOLEAN_FUNCTION_INDEX, prototype, &miss); 2709 masm(), Context::BOOLEAN_FUNCTION_INDEX, prototype, &miss);
2694 CheckPrototypes( 2710 CheckPrototypes(
2695 Handle<JSObject>(JSObject::cast(object->GetPrototype(isolate()))), 2711 Handle<JSObject>(JSObject::cast(object->GetPrototype(isolate()))),
2696 prototype, holder, x3, x1, x4, name, &miss); 2712 prototype, holder, x3, x1, x4, name, &miss);
2697 break; 2713 break;
2698 } 2714 }
2699 } 2715 }
2700 2716
2701 __ B(success); 2717 Label success;
2718 __ B(&success);
2702 2719
2703 // Handle call cache miss. 2720 // Handle call cache miss.
2704 __ Bind(&miss); 2721 __ Bind(&miss);
2705 GenerateMissBranch(); 2722 GenerateMissBranch();
2723
2724 __ Bind(&success);
2706 } 2725 }
2707 2726
2708 2727
2709 void CallStubCompiler::CompileHandlerBackend(Handle<JSFunction> function) { 2728 void CallStubCompiler::CompileHandlerBackend(Handle<JSFunction> function) {
2710 CallKind call_kind = CallICBase::Contextual::decode(extra_state_) 2729 CallKind call_kind = CallICBase::Contextual::decode(extra_state_)
2711 ? CALL_AS_FUNCTION 2730 ? CALL_AS_FUNCTION
2712 : CALL_AS_METHOD; 2731 : CALL_AS_METHOD;
2713 ParameterCount expected(function); 2732 ParameterCount expected(function);
2714 __ InvokeFunction(function, expected, arguments(), 2733 __ InvokeFunction(function, expected, arguments(),
2715 JUMP_FUNCTION, NullCallWrapper(), call_kind); 2734 JUMP_FUNCTION, NullCallWrapper(), call_kind);
2716 } 2735 }
2717 2736
2718 2737
2719 Handle<Code> CallStubCompiler::CompileCallConstant( 2738 Handle<Code> CallStubCompiler::CompileCallConstant(
2720 Handle<Object> object, 2739 Handle<Object> object,
2721 Handle<JSObject> holder, 2740 Handle<JSObject> holder,
2722 Handle<Name> name, 2741 Handle<Name> name,
2723 CheckType check, 2742 CheckType check,
2724 Handle<JSFunction> function) { 2743 Handle<JSFunction> function) {
2725 if (HasCustomCallGenerator(function)) { 2744 if (HasCustomCallGenerator(function)) {
2726 Handle<Code> code = CompileCustomCall(object, holder, 2745 Handle<Code> code = CompileCustomCall(object, holder,
2727 Handle<Cell>::null(), 2746 Handle<Cell>::null(),
2728 function, Handle<String>::cast(name), 2747 function, Handle<String>::cast(name),
2729 Code::CONSTANT); 2748 Code::CONSTANT);
2730 // A null handle means bail out to the regular compiler code below. 2749 // A null handle means bail out to the regular compiler code below.
2731 if (!code.is_null()) return code; 2750 if (!code.is_null()) return code;
2732 } 2751 }
2733 2752
2734 Label success; 2753 CompileHandlerFrontend(object, holder, name, check);
2735
2736 CompileHandlerFrontend(object, holder, name, check, &success);
2737 __ Bind(&success);
2738 CompileHandlerBackend(function); 2754 CompileHandlerBackend(function);
2739 2755
2740 // Return the generated code. 2756 // Return the generated code.
2741 return GetCode(function); 2757 return GetCode(function);
2742 } 2758 }
2743 2759
2744 2760
2745 Handle<Code> CallStubCompiler::CompileCallInterceptor(Handle<JSObject> object, 2761 Handle<Code> CallStubCompiler::CompileCallInterceptor(Handle<JSObject> object,
2746 Handle<JSObject> holder, 2762 Handle<JSObject> holder,
2747 Handle<Name> name) { 2763 Handle<Name> name) {
(...skipping 101 matching lines...) Expand 10 before | Expand all | Expand 10 after
2849 return GetCode(Code::NORMAL, name); 2865 return GetCode(Code::NORMAL, name);
2850 } 2866 }
2851 2867
2852 2868
2853 Handle<Code> StoreStubCompiler::CompileStoreCallback( 2869 Handle<Code> StoreStubCompiler::CompileStoreCallback(
2854 Handle<JSObject> object, 2870 Handle<JSObject> object,
2855 Handle<JSObject> holder, 2871 Handle<JSObject> holder,
2856 Handle<Name> name, 2872 Handle<Name> name,
2857 Handle<ExecutableAccessorInfo> callback) { 2873 Handle<ExecutableAccessorInfo> callback) {
2858 ASM_LOCATION("StoreStubCompiler::CompileStoreCallback"); 2874 ASM_LOCATION("StoreStubCompiler::CompileStoreCallback");
2859 2875 HandlerFrontend(object, receiver(), holder, name);
2860 Label success;
2861 HandlerFrontend(object, receiver(), holder, name, &success);
2862 __ Bind(&success);
2863 2876
2864 // Stub never generated for non-global objects that require access checks. 2877 // Stub never generated for non-global objects that require access checks.
2865 ASSERT(holder->IsJSGlobalProxy() || !holder->IsAccessCheckNeeded()); 2878 ASSERT(holder->IsJSGlobalProxy() || !holder->IsAccessCheckNeeded());
2866 2879
2867 __ Mov(scratch1(), Operand(callback)); 2880 __ Mov(scratch1(), Operand(callback));
2868 __ Mov(scratch2(), Operand(name)); 2881 __ Mov(scratch2(), Operand(name));
2869 __ Push(receiver(), scratch1(), scratch2(), value()); 2882 __ Push(receiver(), scratch1(), scratch2(), value());
2870 2883
2871 // Do tail-call to the runtime system. 2884 // Do tail-call to the runtime system.
2872 ExternalReference store_callback_property = 2885 ExternalReference store_callback_property =
(...skipping 85 matching lines...) Expand 10 before | Expand all | Expand 10 after
2958 // Handle store cache miss. 2971 // Handle store cache miss.
2959 __ Bind(&miss); 2972 __ Bind(&miss);
2960 TailCallBuiltin(masm(), MissBuiltin(kind())); 2973 TailCallBuiltin(masm(), MissBuiltin(kind()));
2961 2974
2962 // Return the generated code. 2975 // Return the generated code.
2963 return GetCode(kind(), Code::INTERCEPTOR, name); 2976 return GetCode(kind(), Code::INTERCEPTOR, name);
2964 } 2977 }
2965 2978
2966 2979
2967 Handle<Code> LoadStubCompiler::CompileLoadNonexistent( 2980 Handle<Code> LoadStubCompiler::CompileLoadNonexistent(
2968 Handle<JSObject> object, 2981 Handle<Object> object,
2969 Handle<JSObject> last, 2982 Handle<JSObject> last,
2970 Handle<Name> name, 2983 Handle<Name> name,
2971 Handle<JSGlobalObject> global) { 2984 Handle<JSGlobalObject> global) {
2972 Label success; 2985 NonexistentHandlerFrontend(object, last, name, global);
2973 NonexistentHandlerFrontend(object, last, name, &success, global);
2974 2986
2975 __ Bind(&success);
2976 // Return undefined if maps of the full prototype chain are still the 2987 // Return undefined if maps of the full prototype chain are still the
2977 // same and no global property with this name contains a value. 2988 // same and no global property with this name contains a value.
2978 __ LoadRoot(x0, Heap::kUndefinedValueRootIndex); 2989 __ LoadRoot(x0, Heap::kUndefinedValueRootIndex);
2979 __ Ret(); 2990 __ Ret();
2980 2991
2981 // Return the generated code. 2992 // Return the generated code.
2982 return GetCode(kind(), Code::NONEXISTENT, name); 2993 return GetCode(kind(), Code::NONEXISTENT, name);
2983 } 2994 }
2984 2995
2985 2996
(...skipping 80 matching lines...) Expand 10 before | Expand all | Expand 10 after
3066 } 3077 }
3067 __ Ret(); 3078 __ Ret();
3068 } 3079 }
3069 3080
3070 3081
3071 #undef __ 3082 #undef __
3072 #define __ ACCESS_MASM(masm()) 3083 #define __ ACCESS_MASM(masm())
3073 3084
3074 3085
3075 Handle<Code> LoadStubCompiler::CompileLoadGlobal( 3086 Handle<Code> LoadStubCompiler::CompileLoadGlobal(
3076 Handle<JSObject> object, 3087 Handle<Object> object,
3077 Handle<GlobalObject> global, 3088 Handle<GlobalObject> global,
3078 Handle<PropertyCell> cell, 3089 Handle<PropertyCell> cell,
3079 Handle<Name> name, 3090 Handle<Name> name,
3080 bool is_dont_delete) { 3091 bool is_dont_delete) {
3081 Label success, miss; 3092 Label miss;
3082 3093
3083 HandlerFrontendHeader(object, receiver(), global, name, &miss); 3094 HandlerFrontendHeader(object, receiver(), global, name, &miss);
3084 3095
3085 // Get the value from the cell. 3096 // Get the value from the cell.
3086 __ Mov(x3, Operand(cell)); 3097 __ Mov(x3, Operand(cell));
3087 __ Ldr(x4, FieldMemOperand(x3, Cell::kValueOffset)); 3098 __ Ldr(x4, FieldMemOperand(x3, Cell::kValueOffset));
3088 3099
3089 // Check for deleted property if property can actually be deleted. 3100 // Check for deleted property if property can actually be deleted.
3090 if (!is_dont_delete) { 3101 if (!is_dont_delete) {
3091 __ JumpIfRoot(x4, Heap::kTheHoleValueRootIndex, &miss); 3102 __ JumpIfRoot(x4, Heap::kTheHoleValueRootIndex, &miss);
3092 } 3103 }
3093 3104
3094 HandlerFrontendFooter(name, &success, &miss); 3105 HandlerFrontendFooter(name, &miss);
3095 __ Bind(&success);
3096 3106
3097 Counters* counters = isolate()->counters(); 3107 Counters* counters = isolate()->counters();
3098 __ IncrementCounter(counters->named_load_global_stub(), 1, x1, x3); 3108 __ IncrementCounter(counters->named_load_global_stub(), 1, x1, x3);
3099 __ Mov(x0, x4); 3109 __ Mov(x0, x4);
3100 __ Ret(); 3110 __ Ret();
3101 3111
3102 // Return the generated code. 3112 // Return the generated code.
3103 return GetCode(kind(), Code::NORMAL, name); 3113 return GetCode(kind(), Code::NORMAL, name);
3104 } 3114 }
3105 3115
3106 3116
3107 Handle<Code> BaseLoadStoreStubCompiler::CompilePolymorphicIC( 3117 Handle<Code> BaseLoadStoreStubCompiler::CompilePolymorphicIC(
3108 MapHandleList* receiver_maps, 3118 MapHandleList* receiver_maps,
3109 CodeHandleList* handlers, 3119 CodeHandleList* handlers,
3110 Handle<Name> name, 3120 Handle<Name> name,
3111 Code::StubType type, 3121 Code::StubType type,
3112 IcCheckType check) { 3122 IcCheckType check) {
3113 Label miss; 3123 Label miss;
3114 3124
3115 if (check == PROPERTY) { 3125 if (check == PROPERTY) {
3116 GenerateNameCheck(name, this->name(), &miss); 3126 GenerateNameCheck(name, this->name(), &miss);
3117 } 3127 }
3118 3128
3119 __ JumpIfSmi(receiver(), &miss); 3129 Label number_case;
3130 Label* smi_target = HasHeapNumberMap(receiver_maps) ? &number_case : &miss;
3131 __ JumpIfSmi(receiver(), smi_target);
3120 3132
3121 Register map_reg = scratch1(); 3133 Register map_reg = scratch1();
3122 __ Ldr(map_reg, FieldMemOperand(receiver(), HeapObject::kMapOffset)); 3134 __ Ldr(map_reg, FieldMemOperand(receiver(), HeapObject::kMapOffset));
3135 Handle<Map> heap_number_map = isolate()->factory()->heap_number_map();
3123 int receiver_count = receiver_maps->length(); 3136 int receiver_count = receiver_maps->length();
3124 int number_of_handled_maps = 0; 3137 int number_of_handled_maps = 0;
3125 for (int current = 0; current < receiver_count; ++current) { 3138 for (int current = 0; current < receiver_count; ++current) {
3126 Handle<Map> map = receiver_maps->at(current); 3139 Handle<Map> map = receiver_maps->at(current);
3127 if (!map->is_deprecated()) { 3140 if (!map->is_deprecated()) {
3128 number_of_handled_maps++; 3141 number_of_handled_maps++;
3129 Label try_next; 3142 Label try_next;
3130 __ Cmp(map_reg, Operand(receiver_maps->at(current))); 3143 __ Cmp(map_reg, Operand(receiver_maps->at(current)));
3131 __ B(ne, &try_next); 3144 __ B(ne, &try_next);
3145 if (map.is_identical_to(heap_number_map)) {
3146 ASSERT(!number_case.is_unused());
3147 __ Bind(&number_case);
3148 }
3132 __ Jump(handlers->at(current), RelocInfo::CODE_TARGET); 3149 __ Jump(handlers->at(current), RelocInfo::CODE_TARGET);
3133 __ Bind(&try_next); 3150 __ Bind(&try_next);
3134 } 3151 }
3135 } 3152 }
3136 ASSERT(number_of_handled_maps != 0); 3153 ASSERT(number_of_handled_maps != 0);
3137 3154
3138 __ Bind(&miss); 3155 __ Bind(&miss);
3139 TailCallBuiltin(masm(), MissBuiltin(kind())); 3156 TailCallBuiltin(masm(), MissBuiltin(kind()));
3140 3157
3141 // Return the generated code. 3158 // Return the generated code.
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after
3177 return GetICCode( 3194 return GetICCode(
3178 kind(), Code::NORMAL, factory()->empty_string(), POLYMORPHIC); 3195 kind(), Code::NORMAL, factory()->empty_string(), POLYMORPHIC);
3179 } 3196 }
3180 3197
3181 3198
3182 Handle<Code> StoreStubCompiler::CompileStoreCallback( 3199 Handle<Code> StoreStubCompiler::CompileStoreCallback(
3183 Handle<JSObject> object, 3200 Handle<JSObject> object,
3184 Handle<JSObject> holder, 3201 Handle<JSObject> holder,
3185 Handle<Name> name, 3202 Handle<Name> name,
3186 const CallOptimization& call_optimization) { 3203 const CallOptimization& call_optimization) {
3187 Label success; 3204 HandlerFrontend(object, receiver(), holder, name);
3188 HandlerFrontend(object, receiver(), holder, name, &success);
3189 __ Bind(&success);
3190 3205
3191 Register values[] = { value() }; 3206 Register values[] = { value() };
3192 GenerateFastApiCall( 3207 GenerateFastApiCall(
3193 masm(), call_optimization, receiver(), scratch3(), 1, values); 3208 masm(), call_optimization, receiver(), scratch3(), 1, values);
3194 3209
3195 // Return the generated code. 3210 // Return the generated code.
3196 return GetCode(kind(), Code::CALLBACKS, name); 3211 return GetCode(kind(), Code::CALLBACKS, name);
3197 } 3212 }
3198 3213
3199 3214
(...skipping 25 matching lines...) Expand all
3225 3240
3226 // Miss case, call the runtime. 3241 // Miss case, call the runtime.
3227 __ Bind(&miss_force_generic); 3242 __ Bind(&miss_force_generic);
3228 TailCallBuiltin(masm, Builtins::kKeyedLoadIC_MissForceGeneric); 3243 TailCallBuiltin(masm, Builtins::kKeyedLoadIC_MissForceGeneric);
3229 } 3244 }
3230 3245
3231 3246
3232 } } // namespace v8::internal 3247 } } // namespace v8::internal
3233 3248
3234 #endif // V8_TARGET_ARCH_A64 3249 #endif // V8_TARGET_ARCH_A64
OLDNEW
« no previous file with comments | « src/a64/macro-assembler-a64.cc ('k') | src/allocation-tracker.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698