OLD | NEW |
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 3144 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3155 // Cache the called function in a feedback vector slot. Cache states | 3155 // Cache the called function in a feedback vector slot. Cache states |
3156 // are uninitialized, monomorphic (indicated by a JSFunction), and | 3156 // are uninitialized, monomorphic (indicated by a JSFunction), and |
3157 // megamorphic. | 3157 // megamorphic. |
3158 // a0 : number of arguments to the construct function | 3158 // a0 : number of arguments to the construct function |
3159 // a1 : the function to call | 3159 // a1 : the function to call |
3160 // a2 : Feedback vector | 3160 // a2 : Feedback vector |
3161 // a3 : slot in feedback vector (Smi) | 3161 // a3 : slot in feedback vector (Smi) |
3162 Label initialize, done, miss, megamorphic, not_array_function; | 3162 Label initialize, done, miss, megamorphic, not_array_function; |
3163 | 3163 |
3164 ASSERT_EQ(*TypeFeedbackInfo::MegamorphicSentinel(masm->isolate()), | 3164 ASSERT_EQ(*TypeFeedbackInfo::MegamorphicSentinel(masm->isolate()), |
3165 masm->isolate()->heap()->undefined_value()); | 3165 masm->isolate()->heap()->megamorphic_symbol()); |
3166 ASSERT_EQ(*TypeFeedbackInfo::UninitializedSentinel(masm->isolate()), | 3166 ASSERT_EQ(*TypeFeedbackInfo::UninitializedSentinel(masm->isolate()), |
3167 masm->isolate()->heap()->the_hole_value()); | 3167 masm->isolate()->heap()->uninitialized_symbol()); |
3168 | 3168 |
3169 // Load the cache state into t0. | 3169 // Load the cache state into t0. |
3170 __ sll(t0, a3, kPointerSizeLog2 - kSmiTagSize); | 3170 __ sll(t0, a3, kPointerSizeLog2 - kSmiTagSize); |
3171 __ Addu(t0, a2, Operand(t0)); | 3171 __ Addu(t0, a2, Operand(t0)); |
3172 __ lw(t0, FieldMemOperand(t0, FixedArray::kHeaderSize)); | 3172 __ lw(t0, FieldMemOperand(t0, FixedArray::kHeaderSize)); |
3173 | 3173 |
3174 // A monomorphic cache hit or an already megamorphic state: invoke the | 3174 // A monomorphic cache hit or an already megamorphic state: invoke the |
3175 // function without changing the state. | 3175 // function without changing the state. |
3176 __ Branch(&done, eq, t0, Operand(a1)); | 3176 __ Branch(&done, eq, t0, Operand(a1)); |
3177 | 3177 |
3178 // If we came here, we need to see if we are the array function. | 3178 // If we came here, we need to see if we are the array function. |
3179 // If we didn't have a matching function, and we didn't find the megamorph | 3179 // If we didn't have a matching function, and we didn't find the megamorph |
3180 // sentinel, then we have in the slot either some other function or an | 3180 // sentinel, then we have in the slot either some other function or an |
3181 // AllocationSite. Do a map check on the object in a3. | 3181 // AllocationSite. Do a map check on the object in a3. |
3182 __ lw(t1, FieldMemOperand(t0, 0)); | 3182 __ lw(t1, FieldMemOperand(t0, 0)); |
3183 __ LoadRoot(at, Heap::kAllocationSiteMapRootIndex); | 3183 __ LoadRoot(at, Heap::kAllocationSiteMapRootIndex); |
3184 __ Branch(&miss, ne, t1, Operand(at)); | 3184 __ Branch(&miss, ne, t1, Operand(at)); |
3185 | 3185 |
3186 // Make sure the function is the Array() function | 3186 // Make sure the function is the Array() function |
3187 __ LoadGlobalFunction(Context::ARRAY_FUNCTION_INDEX, t0); | 3187 __ LoadGlobalFunction(Context::ARRAY_FUNCTION_INDEX, t0); |
3188 __ Branch(&megamorphic, ne, a1, Operand(t0)); | 3188 __ Branch(&megamorphic, ne, a1, Operand(t0)); |
3189 __ jmp(&done); | 3189 __ jmp(&done); |
3190 | 3190 |
3191 __ bind(&miss); | 3191 __ bind(&miss); |
3192 | 3192 |
3193 // A monomorphic miss (i.e, here the cache is not uninitialized) goes | 3193 // A monomorphic miss (i.e, here the cache is not uninitialized) goes |
3194 // megamorphic. | 3194 // megamorphic. |
3195 __ LoadRoot(at, Heap::kTheHoleValueRootIndex); | 3195 __ LoadRoot(at, Heap::kUninitializedSymbolRootIndex); |
3196 __ Branch(&initialize, eq, t0, Operand(at)); | 3196 __ Branch(&initialize, eq, t0, Operand(at)); |
3197 // MegamorphicSentinel is an immortal immovable object (undefined) so no | 3197 // MegamorphicSentinel is an immortal immovable object (undefined) so no |
3198 // write-barrier is needed. | 3198 // write-barrier is needed. |
3199 __ bind(&megamorphic); | 3199 __ bind(&megamorphic); |
3200 __ sll(t0, a3, kPointerSizeLog2 - kSmiTagSize); | 3200 __ sll(t0, a3, kPointerSizeLog2 - kSmiTagSize); |
3201 __ Addu(t0, a2, Operand(t0)); | 3201 __ Addu(t0, a2, Operand(t0)); |
3202 __ LoadRoot(at, Heap::kUndefinedValueRootIndex); | 3202 __ LoadRoot(at, Heap::kMegamorphicSymbolRootIndex); |
3203 __ sw(at, FieldMemOperand(t0, FixedArray::kHeaderSize)); | 3203 __ sw(at, FieldMemOperand(t0, FixedArray::kHeaderSize)); |
3204 __ jmp(&done); | 3204 __ jmp(&done); |
3205 | 3205 |
3206 // An uninitialized cache is patched with the function or sentinel to | 3206 // An uninitialized cache is patched with the function or sentinel to |
3207 // indicate the ElementsKind if function is the Array constructor. | 3207 // indicate the ElementsKind if function is the Array constructor. |
3208 __ bind(&initialize); | 3208 __ bind(&initialize); |
3209 // Make sure the function is the Array() function | 3209 // Make sure the function is the Array() function |
3210 __ LoadGlobalFunction(Context::ARRAY_FUNCTION_INDEX, t0); | 3210 __ LoadGlobalFunction(Context::ARRAY_FUNCTION_INDEX, t0); |
3211 __ Branch(¬_array_function, ne, a1, Operand(t0)); | 3211 __ Branch(¬_array_function, ne, a1, Operand(t0)); |
3212 | 3212 |
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3244 EMIT_REMEMBERED_SET, OMIT_SMI_CHECK); | 3244 EMIT_REMEMBERED_SET, OMIT_SMI_CHECK); |
3245 __ Pop(t0, a2, a1); | 3245 __ Pop(t0, a2, a1); |
3246 | 3246 |
3247 __ bind(&done); | 3247 __ bind(&done); |
3248 } | 3248 } |
3249 | 3249 |
3250 | 3250 |
3251 void CallFunctionStub::Generate(MacroAssembler* masm) { | 3251 void CallFunctionStub::Generate(MacroAssembler* masm) { |
3252 // a1 : the function to call | 3252 // a1 : the function to call |
3253 // a2 : feedback vector | 3253 // a2 : feedback vector |
3254 // a3 : (only if a2 is not undefined) slot in feedback vector (Smi) | 3254 // a3 : (only if a2 is not the megamorphic symbol) slot in feedback |
| 3255 // vector (Smi) |
3255 Label slow, non_function, wrap, cont; | 3256 Label slow, non_function, wrap, cont; |
3256 | 3257 |
3257 if (NeedsChecks()) { | 3258 if (NeedsChecks()) { |
3258 // Check that the function is really a JavaScript function. | 3259 // Check that the function is really a JavaScript function. |
3259 // a1: pushed function (to be verified) | 3260 // a1: pushed function (to be verified) |
3260 __ JumpIfSmi(a1, &non_function); | 3261 __ JumpIfSmi(a1, &non_function); |
3261 | 3262 |
3262 // Goto slow case if we do not have a function. | 3263 // Goto slow case if we do not have a function. |
3263 __ GetObjectType(a1, t0, t0); | 3264 __ GetObjectType(a1, t0, t0); |
3264 __ Branch(&slow, ne, t0, Operand(JS_FUNCTION_TYPE)); | 3265 __ Branch(&slow, ne, t0, Operand(JS_FUNCTION_TYPE)); |
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3298 __ bind(&cont); | 3299 __ bind(&cont); |
3299 } | 3300 } |
3300 __ InvokeFunction(a1, actual, JUMP_FUNCTION, NullCallWrapper()); | 3301 __ InvokeFunction(a1, actual, JUMP_FUNCTION, NullCallWrapper()); |
3301 | 3302 |
3302 if (NeedsChecks()) { | 3303 if (NeedsChecks()) { |
3303 // Slow-case: Non-function called. | 3304 // Slow-case: Non-function called. |
3304 __ bind(&slow); | 3305 __ bind(&slow); |
3305 if (RecordCallTarget()) { | 3306 if (RecordCallTarget()) { |
3306 // If there is a call target cache, mark it megamorphic in the | 3307 // If there is a call target cache, mark it megamorphic in the |
3307 // non-function case. MegamorphicSentinel is an immortal immovable | 3308 // non-function case. MegamorphicSentinel is an immortal immovable |
3308 // object (undefined) so no write barrier is needed. | 3309 // object (megamorphic symbol) so no write barrier is needed. |
3309 ASSERT_EQ(*TypeFeedbackInfo::MegamorphicSentinel(masm->isolate()), | 3310 ASSERT_EQ(*TypeFeedbackInfo::MegamorphicSentinel(masm->isolate()), |
3310 masm->isolate()->heap()->undefined_value()); | 3311 masm->isolate()->heap()->megamorphic_symbol()); |
3311 __ sll(t1, a3, kPointerSizeLog2 - kSmiTagSize); | 3312 __ sll(t1, a3, kPointerSizeLog2 - kSmiTagSize); |
3312 __ Addu(t1, a2, Operand(t1)); | 3313 __ Addu(t1, a2, Operand(t1)); |
3313 __ LoadRoot(at, Heap::kUndefinedValueRootIndex); | 3314 __ LoadRoot(at, Heap::kMegamorphicSymbolRootIndex); |
3314 __ sw(at, FieldMemOperand(t1, FixedArray::kHeaderSize)); | 3315 __ sw(at, FieldMemOperand(t1, FixedArray::kHeaderSize)); |
3315 } | 3316 } |
3316 // Check for function proxy. | 3317 // Check for function proxy. |
3317 __ Branch(&non_function, ne, t0, Operand(JS_FUNCTION_PROXY_TYPE)); | 3318 __ Branch(&non_function, ne, t0, Operand(JS_FUNCTION_PROXY_TYPE)); |
3318 __ push(a1); // Put proxy as additional argument. | 3319 __ push(a1); // Put proxy as additional argument. |
3319 __ li(a0, Operand(argc_ + 1, RelocInfo::NONE32)); | 3320 __ li(a0, Operand(argc_ + 1, RelocInfo::NONE32)); |
3320 __ li(a2, Operand(0, RelocInfo::NONE32)); | 3321 __ li(a2, Operand(0, RelocInfo::NONE32)); |
3321 __ GetBuiltinFunction(a1, Builtins::CALL_FUNCTION_PROXY); | 3322 __ GetBuiltinFunction(a1, Builtins::CALL_FUNCTION_PROXY); |
3322 { | 3323 { |
3323 Handle<Code> adaptor = | 3324 Handle<Code> adaptor = |
(...skipping 2147 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5471 } else { | 5472 } else { |
5472 UNREACHABLE(); | 5473 UNREACHABLE(); |
5473 } | 5474 } |
5474 } | 5475 } |
5475 | 5476 |
5476 | 5477 |
5477 void ArrayConstructorStub::Generate(MacroAssembler* masm) { | 5478 void ArrayConstructorStub::Generate(MacroAssembler* masm) { |
5478 // ----------- S t a t e ------------- | 5479 // ----------- S t a t e ------------- |
5479 // -- a0 : argc (only if argument_count_ == ANY) | 5480 // -- a0 : argc (only if argument_count_ == ANY) |
5480 // -- a1 : constructor | 5481 // -- a1 : constructor |
5481 // -- a2 : feedback vector (fixed array or undefined) | 5482 // -- a2 : feedback vector (fixed array or megamorphic symbol) |
5482 // -- a3 : slot index (if a2 is fixed array) | 5483 // -- a3 : slot index (if a2 is fixed array) |
5483 // -- sp[0] : return address | 5484 // -- sp[0] : return address |
5484 // -- sp[4] : last argument | 5485 // -- sp[4] : last argument |
5485 // ----------------------------------- | 5486 // ----------------------------------- |
| 5487 |
| 5488 ASSERT_EQ(*TypeFeedbackInfo::MegamorphicSentinel(masm->isolate()), |
| 5489 masm->isolate()->heap()->megamorphic_symbol()); |
| 5490 |
5486 if (FLAG_debug_code) { | 5491 if (FLAG_debug_code) { |
5487 // The array construct code is only set for the global and natives | 5492 // The array construct code is only set for the global and natives |
5488 // builtin Array functions which always have maps. | 5493 // builtin Array functions which always have maps. |
5489 | 5494 |
5490 // Initial map for the builtin Array function should be a map. | 5495 // Initial map for the builtin Array function should be a map. |
5491 __ lw(t0, FieldMemOperand(a1, JSFunction::kPrototypeOrInitialMapOffset)); | 5496 __ lw(t0, FieldMemOperand(a1, JSFunction::kPrototypeOrInitialMapOffset)); |
5492 // Will both indicate a NULL and a Smi. | 5497 // Will both indicate a NULL and a Smi. |
5493 __ SmiTst(t0, at); | 5498 __ SmiTst(t0, at); |
5494 __ Assert(ne, kUnexpectedInitialMapForArrayFunction, | 5499 __ Assert(ne, kUnexpectedInitialMapForArrayFunction, |
5495 at, Operand(zero_reg)); | 5500 at, Operand(zero_reg)); |
5496 __ GetObjectType(t0, t0, t1); | 5501 __ GetObjectType(t0, t0, t1); |
5497 __ Assert(eq, kUnexpectedInitialMapForArrayFunction, | 5502 __ Assert(eq, kUnexpectedInitialMapForArrayFunction, |
5498 t1, Operand(MAP_TYPE)); | 5503 t1, Operand(MAP_TYPE)); |
5499 | 5504 |
5500 // We should either have undefined in a2 or a valid fixed array. | 5505 // We should either have the megamorphic symbol in a2 or a valid |
| 5506 // fixed array. |
5501 Label okay_here; | 5507 Label okay_here; |
5502 Handle<Map> fixed_array_map = masm->isolate()->factory()->fixed_array_map(); | 5508 Handle<Map> fixed_array_map = masm->isolate()->factory()->fixed_array_map(); |
5503 __ LoadRoot(at, Heap::kUndefinedValueRootIndex); | 5509 __ LoadRoot(at, Heap::kMegamorphicSymbolRootIndex); |
5504 __ Branch(&okay_here, eq, a2, Operand(at)); | 5510 __ Branch(&okay_here, eq, a2, Operand(at)); |
5505 __ lw(t0, FieldMemOperand(a2, 0)); | 5511 __ lw(t0, FieldMemOperand(a2, 0)); |
5506 __ Assert(eq, kExpectedFixedArrayInRegisterA2, | 5512 __ Assert(eq, kExpectedFixedArrayInRegisterA2, |
5507 t0, Operand(fixed_array_map)); | 5513 t0, Operand(fixed_array_map)); |
5508 | 5514 |
5509 // a3 should be a smi if we don't have undefined in a2 | 5515 // a3 should be a smi if we don't have undefined in a2 |
5510 __ AssertSmi(a3); | 5516 __ AssertSmi(a3); |
5511 | 5517 |
5512 __ bind(&okay_here); | 5518 __ bind(&okay_here); |
5513 } | 5519 } |
5514 | 5520 |
5515 Label no_info; | 5521 Label no_info; |
5516 // Get the elements kind and case on that. | 5522 // Get the elements kind and case on that. |
5517 __ LoadRoot(at, Heap::kUndefinedValueRootIndex); | 5523 __ LoadRoot(at, Heap::kMegamorphicSymbolRootIndex); |
5518 __ Branch(&no_info, eq, a2, Operand(at)); | 5524 __ Branch(&no_info, eq, a2, Operand(at)); |
5519 __ sll(t0, a3, kPointerSizeLog2 - kSmiTagSize); | 5525 __ sll(t0, a3, kPointerSizeLog2 - kSmiTagSize); |
5520 __ Addu(a2, a2, Operand(t0)); | 5526 __ Addu(a2, a2, Operand(t0)); |
5521 __ lw(a2, FieldMemOperand(a2, FixedArray::kHeaderSize)); | 5527 __ lw(a2, FieldMemOperand(a2, FixedArray::kHeaderSize)); |
5522 | 5528 |
5523 // If the feedback vector is undefined, or contains anything other than an | 5529 // If the feedback vector is undefined, or contains anything other than an |
5524 // AllocationSite, call an array constructor that doesn't use AllocationSites. | 5530 // AllocationSite, call an array constructor that doesn't use AllocationSites. |
5525 __ lw(t0, FieldMemOperand(a2, 0)); | 5531 __ lw(t0, FieldMemOperand(a2, 0)); |
5526 __ LoadRoot(at, Heap::kAllocationSiteMapRootIndex); | 5532 __ LoadRoot(at, Heap::kAllocationSiteMapRootIndex); |
5527 __ Branch(&no_info, ne, t0, Operand(at)); | 5533 __ Branch(&no_info, ne, t0, Operand(at)); |
(...skipping 224 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5752 MemOperand(fp, 6 * kPointerSize), | 5758 MemOperand(fp, 6 * kPointerSize), |
5753 NULL); | 5759 NULL); |
5754 } | 5760 } |
5755 | 5761 |
5756 | 5762 |
5757 #undef __ | 5763 #undef __ |
5758 | 5764 |
5759 } } // namespace v8::internal | 5765 } } // namespace v8::internal |
5760 | 5766 |
5761 #endif // V8_TARGET_ARCH_MIPS | 5767 #endif // V8_TARGET_ARCH_MIPS |
OLD | NEW |