OLD | NEW |
1 // Copyright 2011 the V8 project authors. All rights reserved. | 1 // Copyright 2011 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 61 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
72 Label* miss) { | 72 Label* miss) { |
73 // Register usage: | 73 // Register usage: |
74 // receiver: holds the receiver on entry and is unchanged. | 74 // receiver: holds the receiver on entry and is unchanged. |
75 // elements: holds the property dictionary on fall through. | 75 // elements: holds the property dictionary on fall through. |
76 // Scratch registers: | 76 // Scratch registers: |
77 // t0: used to holds the receiver map. | 77 // t0: used to holds the receiver map. |
78 // t1: used to holds the receiver instance type, receiver bit mask and | 78 // t1: used to holds the receiver instance type, receiver bit mask and |
79 // elements map. | 79 // elements map. |
80 | 80 |
81 // Check that the receiver isn't a smi. | 81 // Check that the receiver isn't a smi. |
82 __ tst(receiver, Operand(kSmiTagMask)); | 82 __ JumpIfSmi(receiver, miss); |
83 __ b(eq, miss); | |
84 | 83 |
85 // Check that the receiver is a valid JS object. | 84 // Check that the receiver is a valid JS object. |
86 __ CompareObjectType(receiver, t0, t1, FIRST_SPEC_OBJECT_TYPE); | 85 __ CompareObjectType(receiver, t0, t1, FIRST_SPEC_OBJECT_TYPE); |
87 __ b(lt, miss); | 86 __ b(lt, miss); |
88 | 87 |
89 // If this assert fails, we have to check upper bound too. | 88 // If this assert fails, we have to check upper bound too. |
90 STATIC_ASSERT(LAST_TYPE == LAST_SPEC_OBJECT_TYPE); | 89 STATIC_ASSERT(LAST_TYPE == LAST_SPEC_OBJECT_TYPE); |
91 | 90 |
92 GenerateGlobalInstanceTypeCheck(masm, t1, miss); | 91 GenerateGlobalInstanceTypeCheck(masm, t1, miss); |
93 | 92 |
(...skipping 402 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
496 argc); | 495 argc); |
497 Isolate::Current()->stub_cache()->GenerateProbe( | 496 Isolate::Current()->stub_cache()->GenerateProbe( |
498 masm, flags, r1, r2, r3, r4, r5); | 497 masm, flags, r1, r2, r3, r4, r5); |
499 | 498 |
500 // If the stub cache probing failed, the receiver might be a value. | 499 // If the stub cache probing failed, the receiver might be a value. |
501 // For value objects, we use the map of the prototype objects for | 500 // For value objects, we use the map of the prototype objects for |
502 // the corresponding JSValue for the cache and that is what we need | 501 // the corresponding JSValue for the cache and that is what we need |
503 // to probe. | 502 // to probe. |
504 // | 503 // |
505 // Check for number. | 504 // Check for number. |
506 __ tst(r1, Operand(kSmiTagMask)); | 505 __ JumpIfSmi(r1, &number); |
507 __ b(eq, &number); | |
508 __ CompareObjectType(r1, r3, r3, HEAP_NUMBER_TYPE); | 506 __ CompareObjectType(r1, r3, r3, HEAP_NUMBER_TYPE); |
509 __ b(ne, &non_number); | 507 __ b(ne, &non_number); |
510 __ bind(&number); | 508 __ bind(&number); |
511 StubCompiler::GenerateLoadGlobalFunctionPrototype( | 509 StubCompiler::GenerateLoadGlobalFunctionPrototype( |
512 masm, Context::NUMBER_FUNCTION_INDEX, r1); | 510 masm, Context::NUMBER_FUNCTION_INDEX, r1); |
513 __ b(&probe); | 511 __ b(&probe); |
514 | 512 |
515 // Check for string. | 513 // Check for string. |
516 __ bind(&non_number); | 514 __ bind(&non_number); |
517 __ cmp(r3, Operand(FIRST_NONSTRING_TYPE)); | 515 __ cmp(r3, Operand(FIRST_NONSTRING_TYPE)); |
(...skipping 23 matching lines...) Expand all Loading... |
541 } | 539 } |
542 | 540 |
543 | 541 |
544 static void GenerateFunctionTailCall(MacroAssembler* masm, | 542 static void GenerateFunctionTailCall(MacroAssembler* masm, |
545 int argc, | 543 int argc, |
546 Label* miss, | 544 Label* miss, |
547 Register scratch) { | 545 Register scratch) { |
548 // r1: function | 546 // r1: function |
549 | 547 |
550 // Check that the value isn't a smi. | 548 // Check that the value isn't a smi. |
551 __ tst(r1, Operand(kSmiTagMask)); | 549 __ JumpIfSmi(r1, miss); |
552 __ b(eq, miss); | |
553 | 550 |
554 // Check that the value is a JSFunction. | 551 // Check that the value is a JSFunction. |
555 __ CompareObjectType(r1, scratch, scratch, JS_FUNCTION_TYPE); | 552 __ CompareObjectType(r1, scratch, scratch, JS_FUNCTION_TYPE); |
556 __ b(ne, miss); | 553 __ b(ne, miss); |
557 | 554 |
558 // Invoke the function. | 555 // Invoke the function. |
559 ParameterCount actual(argc); | 556 ParameterCount actual(argc); |
560 __ InvokeFunction(r1, actual, JUMP_FUNCTION, | 557 __ InvokeFunction(r1, actual, JUMP_FUNCTION, |
561 NullCallWrapper(), CALL_AS_METHOD); | 558 NullCallWrapper(), CALL_AS_METHOD); |
562 } | 559 } |
(...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
617 | 614 |
618 // Move result to r1 and leave the internal frame. | 615 // Move result to r1 and leave the internal frame. |
619 __ mov(r1, Operand(r0)); | 616 __ mov(r1, Operand(r0)); |
620 __ LeaveInternalFrame(); | 617 __ LeaveInternalFrame(); |
621 | 618 |
622 // Check if the receiver is a global object of some sort. | 619 // Check if the receiver is a global object of some sort. |
623 // This can happen only for regular CallIC but not KeyedCallIC. | 620 // This can happen only for regular CallIC but not KeyedCallIC. |
624 if (id == IC::kCallIC_Miss) { | 621 if (id == IC::kCallIC_Miss) { |
625 Label invoke, global; | 622 Label invoke, global; |
626 __ ldr(r2, MemOperand(sp, argc * kPointerSize)); // receiver | 623 __ ldr(r2, MemOperand(sp, argc * kPointerSize)); // receiver |
627 __ tst(r2, Operand(kSmiTagMask)); | 624 __ JumpIfSmi(r2, &invoke); |
628 __ b(eq, &invoke); | |
629 __ CompareObjectType(r2, r3, r3, JS_GLOBAL_OBJECT_TYPE); | 625 __ CompareObjectType(r2, r3, r3, JS_GLOBAL_OBJECT_TYPE); |
630 __ b(eq, &global); | 626 __ b(eq, &global); |
631 __ cmp(r3, Operand(JS_BUILTINS_OBJECT_TYPE)); | 627 __ cmp(r3, Operand(JS_BUILTINS_OBJECT_TYPE)); |
632 __ b(ne, &invoke); | 628 __ b(ne, &invoke); |
633 | 629 |
634 // Patch the receiver on the stack. | 630 // Patch the receiver on the stack. |
635 __ bind(&global); | 631 __ bind(&global); |
636 __ ldr(r2, FieldMemOperand(r2, GlobalObject::kGlobalReceiverOffset)); | 632 __ ldr(r2, FieldMemOperand(r2, GlobalObject::kGlobalReceiverOffset)); |
637 __ str(r2, MemOperand(sp, argc * kPointerSize)); | 633 __ str(r2, MemOperand(sp, argc * kPointerSize)); |
638 __ bind(&invoke); | 634 __ bind(&invoke); |
(...skipping 166 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
805 | 801 |
806 | 802 |
807 void KeyedCallIC::GenerateNormal(MacroAssembler* masm, int argc) { | 803 void KeyedCallIC::GenerateNormal(MacroAssembler* masm, int argc) { |
808 // ----------- S t a t e ------------- | 804 // ----------- S t a t e ------------- |
809 // -- r2 : name | 805 // -- r2 : name |
810 // -- lr : return address | 806 // -- lr : return address |
811 // ----------------------------------- | 807 // ----------------------------------- |
812 | 808 |
813 // Check if the name is a string. | 809 // Check if the name is a string. |
814 Label miss; | 810 Label miss; |
815 __ tst(r2, Operand(kSmiTagMask)); | 811 __ JumpIfSmi(r2, &miss); |
816 __ b(eq, &miss); | |
817 __ IsObjectJSStringType(r2, r0, &miss); | 812 __ IsObjectJSStringType(r2, r0, &miss); |
818 | 813 |
819 GenerateCallNormal(masm, argc); | 814 GenerateCallNormal(masm, argc); |
820 __ bind(&miss); | 815 __ bind(&miss); |
821 GenerateMiss(masm, argc); | 816 GenerateMiss(masm, argc); |
822 } | 817 } |
823 | 818 |
824 | 819 |
825 // Defined in ic.cc. | 820 // Defined in ic.cc. |
826 Object* LoadIC_Miss(Arguments args); | 821 Object* LoadIC_Miss(Arguments args); |
(...skipping 377 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1204 Label slow, fast, array, extra; | 1199 Label slow, fast, array, extra; |
1205 | 1200 |
1206 // Register usage. | 1201 // Register usage. |
1207 Register value = r0; | 1202 Register value = r0; |
1208 Register key = r1; | 1203 Register key = r1; |
1209 Register receiver = r2; | 1204 Register receiver = r2; |
1210 Register elements = r3; // Elements array of the receiver. | 1205 Register elements = r3; // Elements array of the receiver. |
1211 // r4 and r5 are used as general scratch registers. | 1206 // r4 and r5 are used as general scratch registers. |
1212 | 1207 |
1213 // Check that the key is a smi. | 1208 // Check that the key is a smi. |
1214 __ tst(key, Operand(kSmiTagMask)); | 1209 __ JumpIfNotSmi(key, &slow); |
1215 __ b(ne, &slow); | |
1216 // Check that the object isn't a smi. | 1210 // Check that the object isn't a smi. |
1217 __ tst(receiver, Operand(kSmiTagMask)); | 1211 __ JumpIfSmi(receiver, &slow); |
1218 __ b(eq, &slow); | |
1219 // Get the map of the object. | 1212 // Get the map of the object. |
1220 __ ldr(r4, FieldMemOperand(receiver, HeapObject::kMapOffset)); | 1213 __ ldr(r4, FieldMemOperand(receiver, HeapObject::kMapOffset)); |
1221 // Check that the receiver does not require access checks. We need | 1214 // Check that the receiver does not require access checks. We need |
1222 // to do this because this generic stub does not perform map checks. | 1215 // to do this because this generic stub does not perform map checks. |
1223 __ ldrb(ip, FieldMemOperand(r4, Map::kBitFieldOffset)); | 1216 __ ldrb(ip, FieldMemOperand(r4, Map::kBitFieldOffset)); |
1224 __ tst(ip, Operand(1 << Map::kIsAccessCheckNeeded)); | 1217 __ tst(ip, Operand(1 << Map::kIsAccessCheckNeeded)); |
1225 __ b(ne, &slow); | 1218 __ b(ne, &slow); |
1226 // Check if the object is a JS array or not. | 1219 // Check if the object is a JS array or not. |
1227 __ ldrb(r4, FieldMemOperand(r4, Map::kInstanceTypeOffset)); | 1220 __ ldrb(r4, FieldMemOperand(r4, Map::kInstanceTypeOffset)); |
1228 __ cmp(r4, Operand(JS_ARRAY_TYPE)); | 1221 __ cmp(r4, Operand(JS_ARRAY_TYPE)); |
(...skipping 326 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1555 Register reg = Assembler::GetRn(instr_at_patch); | 1548 Register reg = Assembler::GetRn(instr_at_patch); |
1556 patcher.masm()->tst(reg, Operand(kSmiTagMask)); | 1549 patcher.masm()->tst(reg, Operand(kSmiTagMask)); |
1557 patcher.EmitCondition(eq); | 1550 patcher.EmitCondition(eq); |
1558 } | 1551 } |
1559 } | 1552 } |
1560 | 1553 |
1561 | 1554 |
1562 } } // namespace v8::internal | 1555 } } // namespace v8::internal |
1563 | 1556 |
1564 #endif // V8_TARGET_ARCH_ARM | 1557 #endif // V8_TARGET_ARCH_ARM |
OLD | NEW |