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

Side by Side Diff: src/ia32/stub-cache-ia32.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/ia32/macro-assembler-ia32.cc ('k') | src/ic.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 1249 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 1260 // 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 1261 // their maps haven't changed. We also need to check that the property
1262 // cell for the property is still empty. 1262 // cell for the property is still empty.
1263 GenerateCheckPropertyCells(masm(), object, holder, name, scratch1, miss); 1263 GenerateCheckPropertyCells(masm(), object, holder, name, scratch1, miss);
1264 1264
1265 // Return the register containing the holder. 1265 // Return the register containing the holder.
1266 return reg; 1266 return reg;
1267 } 1267 }
1268 1268
1269 1269
1270 void LoadStubCompiler::HandlerFrontendFooter(Handle<Name> name, 1270 void LoadStubCompiler::HandlerFrontendFooter(Handle<Name> name, Label* miss) {
1271 Label* success,
1272 Label* miss) {
1273 if (!miss->is_unused()) { 1271 if (!miss->is_unused()) {
1274 __ jmp(success); 1272 Label success;
1273 __ jmp(&success);
1275 __ bind(miss); 1274 __ bind(miss);
1276 TailCallBuiltin(masm(), MissBuiltin(kind())); 1275 TailCallBuiltin(masm(), MissBuiltin(kind()));
1276 __ bind(&success);
1277 } 1277 }
1278 } 1278 }
1279 1279
1280 1280
1281 void StoreStubCompiler::HandlerFrontendFooter(Handle<Name> name, 1281 void StoreStubCompiler::HandlerFrontendFooter(Handle<Name> name, Label* miss) {
1282 Label* success,
1283 Label* miss) {
1284 if (!miss->is_unused()) { 1282 if (!miss->is_unused()) {
1285 __ jmp(success); 1283 Label success;
1284 __ jmp(&success);
1286 GenerateRestoreName(masm(), miss, name); 1285 GenerateRestoreName(masm(), miss, name);
1287 TailCallBuiltin(masm(), MissBuiltin(kind())); 1286 TailCallBuiltin(masm(), MissBuiltin(kind()));
1287 __ bind(&success);
1288 } 1288 }
1289 } 1289 }
1290 1290
1291 1291
1292 Register LoadStubCompiler::CallbackHandlerFrontend( 1292 Register LoadStubCompiler::CallbackHandlerFrontend(
1293 Handle<JSObject> object, 1293 Handle<Object> object,
1294 Register object_reg, 1294 Register object_reg,
1295 Handle<JSObject> holder, 1295 Handle<JSObject> holder,
1296 Handle<Name> name, 1296 Handle<Name> name,
1297 Label* success,
1298 Handle<Object> callback) { 1297 Handle<Object> callback) {
1299 Label miss; 1298 Label miss;
1300 1299
1301 Register reg = HandlerFrontendHeader(object, object_reg, holder, name, &miss); 1300 Register reg = HandlerFrontendHeader(object, object_reg, holder, name, &miss);
1302 1301
1303 if (!holder->HasFastProperties() && !holder->IsJSGlobalObject()) { 1302 if (!holder->HasFastProperties() && !holder->IsJSGlobalObject()) {
1304 ASSERT(!reg.is(scratch2())); 1303 ASSERT(!reg.is(scratch2()));
1305 ASSERT(!reg.is(scratch3())); 1304 ASSERT(!reg.is(scratch3()));
1306 Register dictionary = scratch1(); 1305 Register dictionary = scratch1();
1307 bool must_preserve_dictionary_reg = reg.is(dictionary); 1306 bool must_preserve_dictionary_reg = reg.is(dictionary);
(...skipping 29 matching lines...) Expand all
1337 const int kValueOffset = kElementsStartOffset + kPointerSize; 1336 const int kValueOffset = kElementsStartOffset + kPointerSize;
1338 __ mov(scratch3(), 1337 __ mov(scratch3(),
1339 Operand(dictionary, index, times_4, kValueOffset - kHeapObjectTag)); 1338 Operand(dictionary, index, times_4, kValueOffset - kHeapObjectTag));
1340 if (must_preserve_dictionary_reg) { 1339 if (must_preserve_dictionary_reg) {
1341 __ pop(dictionary); 1340 __ pop(dictionary);
1342 } 1341 }
1343 __ cmp(scratch3(), callback); 1342 __ cmp(scratch3(), callback);
1344 __ j(not_equal, &miss); 1343 __ j(not_equal, &miss);
1345 } 1344 }
1346 1345
1347 HandlerFrontendFooter(name, success, &miss); 1346 HandlerFrontendFooter(name, &miss);
1348 return reg; 1347 return reg;
1349 } 1348 }
1350 1349
1351 1350
1352 void LoadStubCompiler::GenerateLoadField(Register reg, 1351 void LoadStubCompiler::GenerateLoadField(Register reg,
1353 Handle<JSObject> holder, 1352 Handle<JSObject> holder,
1354 PropertyIndex field, 1353 PropertyIndex field,
1355 Representation representation) { 1354 Representation representation) {
1356 if (!reg.is(receiver())) __ mov(receiver(), reg); 1355 if (!reg.is(receiver())) __ mov(receiver(), reg);
1357 if (kind() == Code::LOAD_IC) { 1356 if (kind() == Code::LOAD_IC) {
(...skipping 85 matching lines...) Expand 10 before | Expand all | Expand 10 after
1443 1442
1444 void LoadStubCompiler::GenerateLoadConstant(Handle<Object> value) { 1443 void LoadStubCompiler::GenerateLoadConstant(Handle<Object> value) {
1445 // Return the constant value. 1444 // Return the constant value.
1446 __ LoadObject(eax, value); 1445 __ LoadObject(eax, value);
1447 __ ret(0); 1446 __ ret(0);
1448 } 1447 }
1449 1448
1450 1449
1451 void LoadStubCompiler::GenerateLoadInterceptor( 1450 void LoadStubCompiler::GenerateLoadInterceptor(
1452 Register holder_reg, 1451 Register holder_reg,
1453 Handle<JSObject> object, 1452 Handle<Object> object,
1454 Handle<JSObject> interceptor_holder, 1453 Handle<JSObject> interceptor_holder,
1455 LookupResult* lookup, 1454 LookupResult* lookup,
1456 Handle<Name> name) { 1455 Handle<Name> name) {
1457 ASSERT(interceptor_holder->HasNamedInterceptor()); 1456 ASSERT(interceptor_holder->HasNamedInterceptor());
1458 ASSERT(!interceptor_holder->GetNamedInterceptor()->getter()->IsUndefined()); 1457 ASSERT(!interceptor_holder->GetNamedInterceptor()->getter()->IsUndefined());
1459 1458
1460 // So far the most popular follow ups for interceptor loads are FIELD 1459 // So far the most popular follow ups for interceptor loads are FIELD
1461 // and CALLBACKS, so inline only them, other cases may be added 1460 // and CALLBACKS, so inline only them, other cases may be added
1462 // later. 1461 // later.
1463 bool compile_followup_inline = false; 1462 bool compile_followup_inline = false;
(...skipping 234 matching lines...) Expand 10 before | Expand all | Expand 10 after
1698 CheckPrototypes(Handle<JSObject>::cast(object), edx, holder, ebx, eax, edi, 1697 CheckPrototypes(Handle<JSObject>::cast(object), edx, holder, ebx, eax, edi,
1699 name, &miss); 1698 name, &miss);
1700 } else { 1699 } else {
1701 ASSERT(cell->value() == *function); 1700 ASSERT(cell->value() == *function);
1702 GenerateGlobalReceiverCheck(Handle<JSObject>::cast(object), holder, name, 1701 GenerateGlobalReceiverCheck(Handle<JSObject>::cast(object), holder, name,
1703 &miss); 1702 &miss);
1704 GenerateLoadFunctionFromCell(cell, function, &miss); 1703 GenerateLoadFunctionFromCell(cell, function, &miss);
1705 } 1704 }
1706 1705
1707 Handle<AllocationSite> site = isolate()->factory()->NewAllocationSite(); 1706 Handle<AllocationSite> site = isolate()->factory()->NewAllocationSite();
1708 site->set_transition_info(Smi::FromInt(GetInitialFastElementsKind())); 1707 site->SetElementsKind(GetInitialFastElementsKind());
1709 Handle<Cell> site_feedback_cell = isolate()->factory()->NewCell(site); 1708 Handle<Cell> site_feedback_cell = isolate()->factory()->NewCell(site);
1710 __ mov(eax, Immediate(argc)); 1709 __ mov(eax, Immediate(argc));
1711 __ mov(ebx, site_feedback_cell); 1710 __ mov(ebx, site_feedback_cell);
1712 __ mov(edi, function); 1711 __ mov(edi, function);
1713 1712
1714 ArrayConstructorStub stub(isolate()); 1713 ArrayConstructorStub stub(isolate());
1715 __ TailCallStub(&stub); 1714 __ TailCallStub(&stub);
1716 1715
1717 __ bind(&miss); 1716 __ bind(&miss);
1718 GenerateMissBranch(); 1717 GenerateMissBranch();
(...skipping 11 matching lines...) Expand all
1730 Handle<String> name, 1729 Handle<String> name,
1731 Code::StubType type) { 1730 Code::StubType type) {
1732 // ----------- S t a t e ------------- 1731 // ----------- S t a t e -------------
1733 // -- ecx : name 1732 // -- ecx : name
1734 // -- esp[0] : return address 1733 // -- esp[0] : return address
1735 // -- esp[(argc - n) * 4] : arg[n] (zero-based) 1734 // -- esp[(argc - n) * 4] : arg[n] (zero-based)
1736 // -- ... 1735 // -- ...
1737 // -- esp[(argc + 1) * 4] : receiver 1736 // -- esp[(argc + 1) * 4] : receiver
1738 // ----------------------------------- 1737 // -----------------------------------
1739 1738
1740 // If object is not an array, bail out to regular call. 1739 // If object is not an array or is observed, bail out to regular call.
1741 if (!object->IsJSArray() || !cell.is_null()) { 1740 if (!object->IsJSArray() ||
1741 !cell.is_null() ||
1742 Handle<JSArray>::cast(object)->map()->is_observed()) {
1742 return Handle<Code>::null(); 1743 return Handle<Code>::null();
1743 } 1744 }
1744 1745
1745 Label miss; 1746 Label miss;
1746 1747
1747 GenerateNameCheck(name, &miss); 1748 GenerateNameCheck(name, &miss);
1748 1749
1749 // Get the receiver from the stack. 1750 // Get the receiver from the stack.
1750 const int argc = arguments().immediate(); 1751 const int argc = arguments().immediate();
1751 __ mov(edx, Operand(esp, (argc + 1) * kPointerSize)); 1752 __ mov(edx, Operand(esp, (argc + 1) * kPointerSize));
(...skipping 237 matching lines...) Expand 10 before | Expand all | Expand 10 after
1989 Handle<String> name, 1990 Handle<String> name,
1990 Code::StubType type) { 1991 Code::StubType type) {
1991 // ----------- S t a t e ------------- 1992 // ----------- S t a t e -------------
1992 // -- ecx : name 1993 // -- ecx : name
1993 // -- esp[0] : return address 1994 // -- esp[0] : return address
1994 // -- esp[(argc - n) * 4] : arg[n] (zero-based) 1995 // -- esp[(argc - n) * 4] : arg[n] (zero-based)
1995 // -- ... 1996 // -- ...
1996 // -- esp[(argc + 1) * 4] : receiver 1997 // -- esp[(argc + 1) * 4] : receiver
1997 // ----------------------------------- 1998 // -----------------------------------
1998 1999
1999 // If object is not an array, bail out to regular call. 2000 // If object is not an array or is observed, bail out to regular call.
2000 if (!object->IsJSArray() || !cell.is_null()) { 2001 if (!object->IsJSArray() ||
2002 !cell.is_null() ||
2003 Handle<JSArray>::cast(object)->map()->is_observed()) {
2001 return Handle<Code>::null(); 2004 return Handle<Code>::null();
2002 } 2005 }
2003 2006
2004 Label miss, return_undefined, call_builtin; 2007 Label miss, return_undefined, call_builtin;
2005 2008
2006 GenerateNameCheck(name, &miss); 2009 GenerateNameCheck(name, &miss);
2007 2010
2008 // Get the receiver from the stack. 2011 // Get the receiver from the stack.
2009 const int argc = arguments().immediate(); 2012 const int argc = arguments().immediate();
2010 __ mov(edx, Operand(esp, (argc + 1) * kPointerSize)); 2013 __ mov(edx, Operand(esp, (argc + 1) * kPointerSize));
(...skipping 595 matching lines...) Expand 10 before | Expand all | Expand 10 after
2606 __ add(esp, Immediate(kFastApiCallArguments * kPointerSize)); 2609 __ add(esp, Immediate(kFastApiCallArguments * kPointerSize));
2607 2610
2608 __ bind(&miss_before_stack_reserved); 2611 __ bind(&miss_before_stack_reserved);
2609 GenerateMissBranch(); 2612 GenerateMissBranch();
2610 2613
2611 // Return the generated code. 2614 // Return the generated code.
2612 return GetCode(function); 2615 return GetCode(function);
2613 } 2616 }
2614 2617
2615 2618
2619 void StubCompiler::GenerateBooleanCheck(Register object, Label* miss) {
2620 Label success;
2621 // Check that the object is a boolean.
2622 __ cmp(object, factory()->true_value());
2623 __ j(equal, &success);
2624 __ cmp(object, factory()->false_value());
2625 __ j(not_equal, miss);
2626 __ bind(&success);
2627 }
2628
2629
2616 void CallStubCompiler::CompileHandlerFrontend(Handle<Object> object, 2630 void CallStubCompiler::CompileHandlerFrontend(Handle<Object> object,
2617 Handle<JSObject> holder, 2631 Handle<JSObject> holder,
2618 Handle<Name> name, 2632 Handle<Name> name,
2619 CheckType check, 2633 CheckType check) {
2620 Label* success) {
2621 // ----------- S t a t e ------------- 2634 // ----------- S t a t e -------------
2622 // -- ecx : name 2635 // -- ecx : name
2623 // -- esp[0] : return address 2636 // -- esp[0] : return address
2624 // -- esp[(argc - n) * 4] : arg[n] (zero-based) 2637 // -- esp[(argc - n) * 4] : arg[n] (zero-based)
2625 // -- ... 2638 // -- ...
2626 // -- esp[(argc + 1) * 4] : receiver 2639 // -- esp[(argc + 1) * 4] : receiver
2627 // ----------------------------------- 2640 // -----------------------------------
2628 Label miss; 2641 Label miss;
2629 GenerateNameCheck(name, &miss); 2642 GenerateNameCheck(name, &miss);
2630 2643
(...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after
2689 __ bind(&fast); 2702 __ bind(&fast);
2690 // Check that the maps starting from the prototype haven't changed. 2703 // Check that the maps starting from the prototype haven't changed.
2691 GenerateDirectLoadGlobalFunctionPrototype( 2704 GenerateDirectLoadGlobalFunctionPrototype(
2692 masm(), Context::NUMBER_FUNCTION_INDEX, eax, &miss); 2705 masm(), Context::NUMBER_FUNCTION_INDEX, eax, &miss);
2693 CheckPrototypes( 2706 CheckPrototypes(
2694 Handle<JSObject>(JSObject::cast(object->GetPrototype(isolate()))), 2707 Handle<JSObject>(JSObject::cast(object->GetPrototype(isolate()))),
2695 eax, holder, ebx, edx, edi, name, &miss); 2708 eax, holder, ebx, edx, edi, name, &miss);
2696 break; 2709 break;
2697 } 2710 }
2698 case BOOLEAN_CHECK: { 2711 case BOOLEAN_CHECK: {
2699 Label fast; 2712 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. 2713 // Check that the maps starting from the prototype haven't changed.
2707 GenerateDirectLoadGlobalFunctionPrototype( 2714 GenerateDirectLoadGlobalFunctionPrototype(
2708 masm(), Context::BOOLEAN_FUNCTION_INDEX, eax, &miss); 2715 masm(), Context::BOOLEAN_FUNCTION_INDEX, eax, &miss);
2709 CheckPrototypes( 2716 CheckPrototypes(
2710 Handle<JSObject>(JSObject::cast(object->GetPrototype(isolate()))), 2717 Handle<JSObject>(JSObject::cast(object->GetPrototype(isolate()))),
2711 eax, holder, ebx, edx, edi, name, &miss); 2718 eax, holder, ebx, edx, edi, name, &miss);
2712 break; 2719 break;
2713 } 2720 }
2714 } 2721 }
2715 2722
2716 __ jmp(success); 2723 Label success;
2724 __ jmp(&success);
2717 2725
2718 // Handle call cache miss. 2726 // Handle call cache miss.
2719 __ bind(&miss); 2727 __ bind(&miss);
2720 GenerateMissBranch(); 2728 GenerateMissBranch();
2729
2730 __ bind(&success);
2721 } 2731 }
2722 2732
2723 2733
2724 void CallStubCompiler::CompileHandlerBackend(Handle<JSFunction> function) { 2734 void CallStubCompiler::CompileHandlerBackend(Handle<JSFunction> function) {
2725 CallKind call_kind = CallICBase::Contextual::decode(extra_state_) 2735 CallKind call_kind = CallICBase::Contextual::decode(extra_state_)
2726 ? CALL_AS_FUNCTION 2736 ? CALL_AS_FUNCTION
2727 : CALL_AS_METHOD; 2737 : CALL_AS_METHOD;
2728 ParameterCount expected(function); 2738 ParameterCount expected(function);
2729 __ InvokeFunction(function, expected, arguments(), 2739 __ InvokeFunction(function, expected, arguments(),
2730 JUMP_FUNCTION, NullCallWrapper(), call_kind); 2740 JUMP_FUNCTION, NullCallWrapper(), call_kind);
2731 } 2741 }
2732 2742
2733 2743
2734 Handle<Code> CallStubCompiler::CompileCallConstant( 2744 Handle<Code> CallStubCompiler::CompileCallConstant(
2735 Handle<Object> object, 2745 Handle<Object> object,
2736 Handle<JSObject> holder, 2746 Handle<JSObject> holder,
2737 Handle<Name> name, 2747 Handle<Name> name,
2738 CheckType check, 2748 CheckType check,
2739 Handle<JSFunction> function) { 2749 Handle<JSFunction> function) {
2740 2750
2741 if (HasCustomCallGenerator(function)) { 2751 if (HasCustomCallGenerator(function)) {
2742 Handle<Code> code = CompileCustomCall(object, holder, 2752 Handle<Code> code = CompileCustomCall(object, holder,
2743 Handle<Cell>::null(), 2753 Handle<Cell>::null(),
2744 function, Handle<String>::cast(name), 2754 function, Handle<String>::cast(name),
2745 Code::CONSTANT); 2755 Code::CONSTANT);
2746 // A null handle means bail out to the regular compiler code below. 2756 // A null handle means bail out to the regular compiler code below.
2747 if (!code.is_null()) return code; 2757 if (!code.is_null()) return code;
2748 } 2758 }
2749 2759
2750 Label success; 2760 CompileHandlerFrontend(object, holder, name, check);
2751
2752 CompileHandlerFrontend(object, holder, name, check, &success);
2753 __ bind(&success);
2754 CompileHandlerBackend(function); 2761 CompileHandlerBackend(function);
2755 2762
2756 // Return the generated code. 2763 // Return the generated code.
2757 return GetCode(function); 2764 return GetCode(function);
2758 } 2765 }
2759 2766
2760 2767
2761 Handle<Code> CallStubCompiler::CompileCallInterceptor(Handle<JSObject> object, 2768 Handle<Code> CallStubCompiler::CompileCallInterceptor(Handle<JSObject> object,
2762 Handle<JSObject> holder, 2769 Handle<JSObject> holder,
2763 Handle<Name> name) { 2770 Handle<Name> name) {
(...skipping 114 matching lines...) Expand 10 before | Expand all | Expand 10 after
2878 // Return the generated code. 2885 // Return the generated code.
2879 return GetCode(Code::NORMAL, name); 2886 return GetCode(Code::NORMAL, name);
2880 } 2887 }
2881 2888
2882 2889
2883 Handle<Code> StoreStubCompiler::CompileStoreCallback( 2890 Handle<Code> StoreStubCompiler::CompileStoreCallback(
2884 Handle<JSObject> object, 2891 Handle<JSObject> object,
2885 Handle<JSObject> holder, 2892 Handle<JSObject> holder,
2886 Handle<Name> name, 2893 Handle<Name> name,
2887 Handle<ExecutableAccessorInfo> callback) { 2894 Handle<ExecutableAccessorInfo> callback) {
2888 Label success; 2895 HandlerFrontend(object, receiver(), holder, name);
2889 HandlerFrontend(object, receiver(), holder, name, &success);
2890 __ bind(&success);
2891 2896
2892 __ pop(scratch1()); // remove the return address 2897 __ pop(scratch1()); // remove the return address
2893 __ push(receiver()); 2898 __ push(receiver());
2894 __ Push(callback); 2899 __ Push(callback);
2895 __ Push(name); 2900 __ Push(name);
2896 __ push(value()); 2901 __ push(value());
2897 __ push(scratch1()); // restore return address 2902 __ push(scratch1()); // restore return address
2898 2903
2899 // Do tail-call to the runtime system. 2904 // Do tail-call to the runtime system.
2900 ExternalReference store_callback_property = 2905 ExternalReference store_callback_property =
2901 ExternalReference(IC_Utility(IC::kStoreCallbackProperty), isolate()); 2906 ExternalReference(IC_Utility(IC::kStoreCallbackProperty), isolate());
2902 __ TailCallExternalReference(store_callback_property, 4, 1); 2907 __ TailCallExternalReference(store_callback_property, 4, 1);
2903 2908
2904 // Return the generated code. 2909 // Return the generated code.
2905 return GetCode(kind(), Code::CALLBACKS, name); 2910 return GetCode(kind(), Code::CALLBACKS, name);
2906 } 2911 }
2907 2912
2908 2913
2909 Handle<Code> StoreStubCompiler::CompileStoreCallback( 2914 Handle<Code> StoreStubCompiler::CompileStoreCallback(
2910 Handle<JSObject> object, 2915 Handle<JSObject> object,
2911 Handle<JSObject> holder, 2916 Handle<JSObject> holder,
2912 Handle<Name> name, 2917 Handle<Name> name,
2913 const CallOptimization& call_optimization) { 2918 const CallOptimization& call_optimization) {
2914 Label success; 2919 HandlerFrontend(object, receiver(), holder, name);
2915 HandlerFrontend(object, receiver(), holder, name, &success);
2916 __ bind(&success);
2917 2920
2918 Register values[] = { value() }; 2921 Register values[] = { value() };
2919 GenerateFastApiCall( 2922 GenerateFastApiCall(
2920 masm(), call_optimization, receiver(), scratch1(), 1, values); 2923 masm(), call_optimization, receiver(), scratch1(), 1, values);
2921 2924
2922 // Return the generated code. 2925 // Return the generated code.
2923 return GetCode(kind(), Code::CALLBACKS, name); 2926 return GetCode(kind(), Code::CALLBACKS, name);
2924 } 2927 }
2925 2928
2926 2929
(...skipping 86 matching lines...) Expand 10 before | Expand all | Expand 10 after
3013 __ bind(&miss); 3016 __ bind(&miss);
3014 TailCallBuiltin(masm(), MissBuiltin(kind())); 3017 TailCallBuiltin(masm(), MissBuiltin(kind()));
3015 3018
3016 // Return the generated code. 3019 // Return the generated code.
3017 return GetICCode( 3020 return GetICCode(
3018 kind(), Code::NORMAL, factory()->empty_string(), POLYMORPHIC); 3021 kind(), Code::NORMAL, factory()->empty_string(), POLYMORPHIC);
3019 } 3022 }
3020 3023
3021 3024
3022 Handle<Code> LoadStubCompiler::CompileLoadNonexistent( 3025 Handle<Code> LoadStubCompiler::CompileLoadNonexistent(
3023 Handle<JSObject> object, 3026 Handle<Object> object,
3024 Handle<JSObject> last, 3027 Handle<JSObject> last,
3025 Handle<Name> name, 3028 Handle<Name> name,
3026 Handle<JSGlobalObject> global) { 3029 Handle<JSGlobalObject> global) {
3027 Label success; 3030 NonexistentHandlerFrontend(object, last, name, global);
3028 3031
3029 NonexistentHandlerFrontend(object, last, name, &success, global);
3030
3031 __ bind(&success);
3032 // Return undefined if maps of the full prototype chain are still the 3032 // Return undefined if maps of the full prototype chain are still the
3033 // same and no global property with this name contains a value. 3033 // same and no global property with this name contains a value.
3034 __ mov(eax, isolate()->factory()->undefined_value()); 3034 __ mov(eax, isolate()->factory()->undefined_value());
3035 __ ret(0); 3035 __ ret(0);
3036 3036
3037 // Return the generated code. 3037 // Return the generated code.
3038 return GetCode(kind(), Code::NONEXISTENT, name); 3038 return GetCode(kind(), Code::NONEXISTENT, name);
3039 } 3039 }
3040 3040
3041 3041
(...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after
3111 } 3111 }
3112 __ ret(0); 3112 __ ret(0);
3113 } 3113 }
3114 3114
3115 3115
3116 #undef __ 3116 #undef __
3117 #define __ ACCESS_MASM(masm()) 3117 #define __ ACCESS_MASM(masm())
3118 3118
3119 3119
3120 Handle<Code> LoadStubCompiler::CompileLoadGlobal( 3120 Handle<Code> LoadStubCompiler::CompileLoadGlobal(
3121 Handle<JSObject> object, 3121 Handle<Object> object,
3122 Handle<GlobalObject> global, 3122 Handle<GlobalObject> global,
3123 Handle<PropertyCell> cell, 3123 Handle<PropertyCell> cell,
3124 Handle<Name> name, 3124 Handle<Name> name,
3125 bool is_dont_delete) { 3125 bool is_dont_delete) {
3126 Label success, miss; 3126 Label miss;
3127 3127
3128 HandlerFrontendHeader(object, receiver(), global, name, &miss); 3128 HandlerFrontendHeader(object, receiver(), global, name, &miss);
3129 // Get the value from the cell. 3129 // Get the value from the cell.
3130 if (Serializer::enabled()) { 3130 if (Serializer::enabled()) {
3131 __ mov(eax, Immediate(cell)); 3131 __ mov(eax, Immediate(cell));
3132 __ mov(eax, FieldOperand(eax, PropertyCell::kValueOffset)); 3132 __ mov(eax, FieldOperand(eax, PropertyCell::kValueOffset));
3133 } else { 3133 } else {
3134 __ mov(eax, Operand::ForCell(cell)); 3134 __ mov(eax, Operand::ForCell(cell));
3135 } 3135 }
3136 3136
3137 // Check for deleted property if property can actually be deleted. 3137 // Check for deleted property if property can actually be deleted.
3138 if (!is_dont_delete) { 3138 if (!is_dont_delete) {
3139 __ cmp(eax, factory()->the_hole_value()); 3139 __ cmp(eax, factory()->the_hole_value());
3140 __ j(equal, &miss); 3140 __ j(equal, &miss);
3141 } else if (FLAG_debug_code) { 3141 } else if (FLAG_debug_code) {
3142 __ cmp(eax, factory()->the_hole_value()); 3142 __ cmp(eax, factory()->the_hole_value());
3143 __ Check(not_equal, kDontDeleteCellsCannotContainTheHole); 3143 __ Check(not_equal, kDontDeleteCellsCannotContainTheHole);
3144 } 3144 }
3145 3145
3146 HandlerFrontendFooter(name, &success, &miss); 3146 HandlerFrontendFooter(name, &miss);
3147 __ bind(&success);
3148 3147
3149 Counters* counters = isolate()->counters(); 3148 Counters* counters = isolate()->counters();
3150 __ IncrementCounter(counters->named_load_global_stub(), 1); 3149 __ IncrementCounter(counters->named_load_global_stub(), 1);
3151 // The code above already loads the result into the return register. 3150 // The code above already loads the result into the return register.
3152 __ ret(0); 3151 __ ret(0);
3153 3152
3154 // Return the generated code. 3153 // Return the generated code.
3155 return GetCode(kind(), Code::NORMAL, name); 3154 return GetCode(kind(), Code::NORMAL, name);
3156 } 3155 }
3157 3156
3158 3157
3159 Handle<Code> BaseLoadStoreStubCompiler::CompilePolymorphicIC( 3158 Handle<Code> BaseLoadStoreStubCompiler::CompilePolymorphicIC(
3160 MapHandleList* receiver_maps, 3159 MapHandleList* receiver_maps,
3161 CodeHandleList* handlers, 3160 CodeHandleList* handlers,
3162 Handle<Name> name, 3161 Handle<Name> name,
3163 Code::StubType type, 3162 Code::StubType type,
3164 IcCheckType check) { 3163 IcCheckType check) {
3165 Label miss; 3164 Label miss;
3166 3165
3167 if (check == PROPERTY) { 3166 if (check == PROPERTY) {
3168 GenerateNameCheck(name, this->name(), &miss); 3167 GenerateNameCheck(name, this->name(), &miss);
3169 } 3168 }
3170 3169
3171 __ JumpIfSmi(receiver(), &miss); 3170 Label number_case;
3171 Label* smi_target = HasHeapNumberMap(receiver_maps) ? &number_case : &miss;
3172 __ JumpIfSmi(receiver(), smi_target);
3173
3172 Register map_reg = scratch1(); 3174 Register map_reg = scratch1();
3173 __ mov(map_reg, FieldOperand(receiver(), HeapObject::kMapOffset)); 3175 __ mov(map_reg, FieldOperand(receiver(), HeapObject::kMapOffset));
3174 int receiver_count = receiver_maps->length(); 3176 int receiver_count = receiver_maps->length();
3175 int number_of_handled_maps = 0; 3177 int number_of_handled_maps = 0;
3178 Handle<Map> heap_number_map = isolate()->factory()->heap_number_map();
3176 for (int current = 0; current < receiver_count; ++current) { 3179 for (int current = 0; current < receiver_count; ++current) {
3177 Handle<Map> map = receiver_maps->at(current); 3180 Handle<Map> map = receiver_maps->at(current);
3178 if (!map->is_deprecated()) { 3181 if (!map->is_deprecated()) {
3179 number_of_handled_maps++; 3182 number_of_handled_maps++;
3180 __ cmp(map_reg, map); 3183 __ cmp(map_reg, map);
3184 if (map.is_identical_to(heap_number_map)) {
3185 ASSERT(!number_case.is_unused());
3186 __ bind(&number_case);
3187 }
3181 __ j(equal, handlers->at(current)); 3188 __ j(equal, handlers->at(current));
3182 } 3189 }
3183 } 3190 }
3184 ASSERT(number_of_handled_maps != 0); 3191 ASSERT(number_of_handled_maps != 0);
3185 3192
3186 __ bind(&miss); 3193 __ bind(&miss);
3187 TailCallBuiltin(masm(), MissBuiltin(kind())); 3194 TailCallBuiltin(masm(), MissBuiltin(kind()));
3188 3195
3189 // Return the generated code. 3196 // Return the generated code.
3190 InlineCacheState state = 3197 InlineCacheState state =
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after
3239 // ----------------------------------- 3246 // -----------------------------------
3240 TailCallBuiltin(masm, Builtins::kKeyedLoadIC_MissForceGeneric); 3247 TailCallBuiltin(masm, Builtins::kKeyedLoadIC_MissForceGeneric);
3241 } 3248 }
3242 3249
3243 3250
3244 #undef __ 3251 #undef __
3245 3252
3246 } } // namespace v8::internal 3253 } } // namespace v8::internal
3247 3254
3248 #endif // V8_TARGET_ARCH_IA32 3255 #endif // V8_TARGET_ARCH_IA32
OLDNEW
« no previous file with comments | « 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