| 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 |