| OLD | NEW |
| 1 // Copyright 2006-2008 the V8 project authors. All rights reserved. | 1 // Copyright 2006-2008 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 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 52 // | 52 // |
| 53 // t0 - used to hold the property dictionary. | 53 // t0 - used to hold the property dictionary. |
| 54 // | 54 // |
| 55 // t1 - initially the receiver | 55 // t1 - initially the receiver |
| 56 // - used for the index into the property dictionary | 56 // - used for the index into the property dictionary |
| 57 // - holds the result on exit. | 57 // - holds the result on exit. |
| 58 // | 58 // |
| 59 // r3 - used as temporary and to hold the capacity of the property | 59 // r3 - used as temporary and to hold the capacity of the property |
| 60 // dictionary. | 60 // dictionary. |
| 61 // | 61 // |
| 62 // r2 - holds the name of the property and is unchanges. | 62 // r2 - holds the name of the property and is unchanged. |
| 63 | 63 |
| 64 Label done; | 64 Label done; |
| 65 | 65 |
| 66 // Check for the absence of an interceptor. | 66 // Check for the absence of an interceptor. |
| 67 // Load the map into t0. | 67 // Load the map into t0. |
| 68 __ ldr(t0, FieldMemOperand(t1, JSObject::kMapOffset)); | 68 __ ldr(t0, FieldMemOperand(t1, JSObject::kMapOffset)); |
| 69 // Test the has_named_interceptor bit in the map. | 69 // Test the has_named_interceptor bit in the map. |
| 70 __ ldr(r3, FieldMemOperand(t0, Map::kInstanceAttributesOffset)); | 70 __ ldr(r3, FieldMemOperand(t0, Map::kInstanceAttributesOffset)); |
| 71 __ tst(r3, Operand(1 << (Map::kHasNamedInterceptor + (3 * 8)))); | 71 __ tst(r3, Operand(1 << (Map::kHasNamedInterceptor + (3 * 8)))); |
| 72 // Jump to miss if the interceptor bit is set. | 72 // Jump to miss if the interceptor bit is set. |
| (...skipping 139 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 212 __ bind(&miss); | 212 __ bind(&miss); |
| 213 StubCompiler::GenerateLoadMiss(masm, Code::LOAD_IC); | 213 StubCompiler::GenerateLoadMiss(masm, Code::LOAD_IC); |
| 214 } | 214 } |
| 215 | 215 |
| 216 | 216 |
| 217 // Defined in ic.cc. | 217 // Defined in ic.cc. |
| 218 Object* CallIC_Miss(Arguments args); | 218 Object* CallIC_Miss(Arguments args); |
| 219 | 219 |
| 220 void CallIC::GenerateMegamorphic(MacroAssembler* masm, int argc) { | 220 void CallIC::GenerateMegamorphic(MacroAssembler* masm, int argc) { |
| 221 // ----------- S t a t e ------------- | 221 // ----------- S t a t e ------------- |
| 222 // -- lr: return address | 222 // -- r2 : name |
| 223 // -- lr : return address |
| 223 // ----------------------------------- | 224 // ----------------------------------- |
| 224 Label number, non_number, non_string, boolean, probe, miss; | 225 Label number, non_number, non_string, boolean, probe, miss; |
| 225 | 226 |
| 226 // Get the receiver of the function from the stack into r1. | 227 // Get the receiver of the function from the stack into r1. |
| 227 __ ldr(r1, MemOperand(sp, argc * kPointerSize)); | 228 __ ldr(r1, MemOperand(sp, argc * kPointerSize)); |
| 228 // Get the name of the function from the stack; 1 ~ receiver. | |
| 229 __ ldr(r2, MemOperand(sp, (argc + 1) * kPointerSize)); | |
| 230 | 229 |
| 231 // Probe the stub cache. | 230 // Probe the stub cache. |
| 232 Code::Flags flags = | 231 Code::Flags flags = |
| 233 Code::ComputeFlags(Code::CALL_IC, NOT_IN_LOOP, MONOMORPHIC, NORMAL, argc); | 232 Code::ComputeFlags(Code::CALL_IC, NOT_IN_LOOP, MONOMORPHIC, NORMAL, argc); |
| 234 StubCache::GenerateProbe(masm, flags, r1, r2, r3, no_reg); | 233 StubCache::GenerateProbe(masm, flags, r1, r2, r3, no_reg); |
| 235 | 234 |
| 236 // If the stub cache probing failed, the receiver might be a value. | 235 // If the stub cache probing failed, the receiver might be a value. |
| 237 // For value objects, we use the map of the prototype objects for | 236 // For value objects, we use the map of the prototype objects for |
| 238 // the corresponding JSValue for the cache and that is what we need | 237 // the corresponding JSValue for the cache and that is what we need |
| 239 // to probe. | 238 // to probe. |
| (...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 294 __ b(ne, miss); | 293 __ b(ne, miss); |
| 295 | 294 |
| 296 // Check that the function has been loaded. | 295 // Check that the function has been loaded. |
| 297 __ ldr(r0, FieldMemOperand(r1, JSObject::kMapOffset)); | 296 __ ldr(r0, FieldMemOperand(r1, JSObject::kMapOffset)); |
| 298 __ ldrb(r0, FieldMemOperand(r0, Map::kBitField2Offset)); | 297 __ ldrb(r0, FieldMemOperand(r0, Map::kBitField2Offset)); |
| 299 __ tst(r0, Operand(1 << Map::kNeedsLoading)); | 298 __ tst(r0, Operand(1 << Map::kNeedsLoading)); |
| 300 __ b(ne, miss); | 299 __ b(ne, miss); |
| 301 | 300 |
| 302 // Patch the receiver with the global proxy if necessary. | 301 // Patch the receiver with the global proxy if necessary. |
| 303 if (is_global_object) { | 302 if (is_global_object) { |
| 304 __ ldr(r2, MemOperand(sp, argc * kPointerSize)); | 303 __ ldr(r0, MemOperand(sp, argc * kPointerSize)); |
| 305 __ ldr(r2, FieldMemOperand(r2, GlobalObject::kGlobalReceiverOffset)); | 304 __ ldr(r0, FieldMemOperand(r0, GlobalObject::kGlobalReceiverOffset)); |
| 306 __ str(r2, MemOperand(sp, argc * kPointerSize)); | 305 __ str(r0, MemOperand(sp, argc * kPointerSize)); |
| 307 } | 306 } |
| 308 | 307 |
| 309 // Invoke the function. | 308 // Invoke the function. |
| 310 ParameterCount actual(argc); | 309 ParameterCount actual(argc); |
| 311 __ InvokeFunction(r1, actual, JUMP_FUNCTION); | 310 __ InvokeFunction(r1, actual, JUMP_FUNCTION); |
| 312 } | 311 } |
| 313 | 312 |
| 314 | 313 |
| 315 void CallIC::GenerateNormal(MacroAssembler* masm, int argc) { | 314 void CallIC::GenerateNormal(MacroAssembler* masm, int argc) { |
| 316 // ----------- S t a t e ------------- | 315 // ----------- S t a t e ------------- |
| 317 // -- lr: return address | 316 // -- r2 : name |
| 317 // -- lr : return address |
| 318 // ----------------------------------- | 318 // ----------------------------------- |
| 319 Label miss, global_object, non_global_object; | 319 Label miss, global_object, non_global_object; |
| 320 | 320 |
| 321 // Get the receiver of the function from the stack into r1. | 321 // Get the receiver of the function from the stack into r1. |
| 322 __ ldr(r1, MemOperand(sp, argc * kPointerSize)); | 322 __ ldr(r1, MemOperand(sp, argc * kPointerSize)); |
| 323 // Get the name of the function from the stack; 1 ~ receiver. | |
| 324 __ ldr(r2, MemOperand(sp, (argc + 1) * kPointerSize)); | |
| 325 | 323 |
| 326 // Check that the receiver isn't a smi. | 324 // Check that the receiver isn't a smi. |
| 327 __ tst(r1, Operand(kSmiTagMask)); | 325 __ tst(r1, Operand(kSmiTagMask)); |
| 328 __ b(eq, &miss); | 326 __ b(eq, &miss); |
| 329 | 327 |
| 330 // Check that the receiver is a valid JS object. Put the map in r3. | 328 // Check that the receiver is a valid JS object. Put the map in r3. |
| 331 __ CompareObjectType(r1, r3, r0, FIRST_JS_OBJECT_TYPE); | 329 __ CompareObjectType(r1, r3, r0, FIRST_JS_OBJECT_TYPE); |
| 332 __ b(lt, &miss); | 330 __ b(lt, &miss); |
| 333 | 331 |
| 334 // If this assert fails, we have to check upper bound too. | 332 // If this assert fails, we have to check upper bound too. |
| (...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 367 __ b(&invoke); | 365 __ b(&invoke); |
| 368 | 366 |
| 369 // Cache miss: Jump to runtime. | 367 // Cache miss: Jump to runtime. |
| 370 __ bind(&miss); | 368 __ bind(&miss); |
| 371 GenerateMiss(masm, argc); | 369 GenerateMiss(masm, argc); |
| 372 } | 370 } |
| 373 | 371 |
| 374 | 372 |
| 375 void CallIC::GenerateMiss(MacroAssembler* masm, int argc) { | 373 void CallIC::GenerateMiss(MacroAssembler* masm, int argc) { |
| 376 // ----------- S t a t e ------------- | 374 // ----------- S t a t e ------------- |
| 377 // -- lr: return address | 375 // -- r2 : name |
| 376 // -- lr : return address |
| 378 // ----------------------------------- | 377 // ----------------------------------- |
| 379 | 378 |
| 380 // Get the receiver of the function from the stack. | 379 // Get the receiver of the function from the stack. |
| 381 __ ldr(r2, MemOperand(sp, argc * kPointerSize)); | 380 __ ldr(r3, MemOperand(sp, argc * kPointerSize)); |
| 382 // Get the name of the function to call from the stack. | |
| 383 __ ldr(r1, MemOperand(sp, (argc + 1) * kPointerSize)); | |
| 384 | 381 |
| 385 __ EnterInternalFrame(); | 382 __ EnterInternalFrame(); |
| 386 | 383 |
| 387 // Push the receiver and the name of the function. | 384 // Push the receiver and the name of the function. |
| 388 __ stm(db_w, sp, r1.bit() | r2.bit()); | 385 __ stm(db_w, sp, r2.bit() | r3.bit()); |
| 389 | 386 |
| 390 // Call the entry. | 387 // Call the entry. |
| 391 __ mov(r0, Operand(2)); | 388 __ mov(r0, Operand(2)); |
| 392 __ mov(r1, Operand(ExternalReference(IC_Utility(kCallIC_Miss)))); | 389 __ mov(r1, Operand(ExternalReference(IC_Utility(kCallIC_Miss)))); |
| 393 | 390 |
| 394 CEntryStub stub(1); | 391 CEntryStub stub(1); |
| 395 __ CallStub(&stub); | 392 __ CallStub(&stub); |
| 396 | 393 |
| 397 // Move result to r1 and leave the internal frame. | 394 // Move result to r1 and leave the internal frame. |
| 398 __ mov(r1, Operand(r0)); | 395 __ mov(r1, Operand(r0)); |
| (...skipping 426 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 825 | 822 |
| 826 // Perform tail call to the entry. | 823 // Perform tail call to the entry. |
| 827 __ TailCallRuntime(ExternalReference(IC_Utility(kStoreIC_Miss)), 3, 1); | 824 __ TailCallRuntime(ExternalReference(IC_Utility(kStoreIC_Miss)), 3, 1); |
| 828 } | 825 } |
| 829 | 826 |
| 830 | 827 |
| 831 #undef __ | 828 #undef __ |
| 832 | 829 |
| 833 | 830 |
| 834 } } // namespace v8::internal | 831 } } // namespace v8::internal |
| OLD | NEW |