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