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 2405 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2416 __ pop(edx); | 2416 __ pop(edx); |
2417 __ pop(ebx); | 2417 __ pop(ebx); |
2418 __ pop(edi); | 2418 __ pop(edi); |
2419 | 2419 |
2420 __ bind(&done); | 2420 __ bind(&done); |
2421 } | 2421 } |
2422 | 2422 |
2423 | 2423 |
2424 void CallFunctionStub::Generate(MacroAssembler* masm) { | 2424 void CallFunctionStub::Generate(MacroAssembler* masm) { |
2425 // ebx : feedback vector | 2425 // ebx : feedback vector |
2426 // edx : (only if ebx is not undefined) slot in feedback vector (Smi) | 2426 // edx : (only if ebx is not the megamorphic symbol) slot in feedback |
| 2427 // vector (Smi) |
2427 // edi : the function to call | 2428 // edi : the function to call |
2428 Isolate* isolate = masm->isolate(); | 2429 Isolate* isolate = masm->isolate(); |
2429 Label slow, non_function, wrap, cont; | 2430 Label slow, non_function, wrap, cont; |
2430 | 2431 |
2431 if (NeedsChecks()) { | 2432 if (NeedsChecks()) { |
2432 // Check that the function really is a JavaScript function. | 2433 // Check that the function really is a JavaScript function. |
2433 __ JumpIfSmi(edi, &non_function); | 2434 __ JumpIfSmi(edi, &non_function); |
2434 | 2435 |
2435 // Goto slow case if we do not have a function. | 2436 // Goto slow case if we do not have a function. |
2436 __ CmpObjectType(edi, JS_FUNCTION_TYPE, ecx); | 2437 __ CmpObjectType(edi, JS_FUNCTION_TYPE, ecx); |
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2474 } | 2475 } |
2475 | 2476 |
2476 __ InvokeFunction(edi, actual, JUMP_FUNCTION, NullCallWrapper()); | 2477 __ InvokeFunction(edi, actual, JUMP_FUNCTION, NullCallWrapper()); |
2477 | 2478 |
2478 if (NeedsChecks()) { | 2479 if (NeedsChecks()) { |
2479 // Slow-case: Non-function called. | 2480 // Slow-case: Non-function called. |
2480 __ bind(&slow); | 2481 __ bind(&slow); |
2481 if (RecordCallTarget()) { | 2482 if (RecordCallTarget()) { |
2482 // If there is a call target cache, mark it megamorphic in the | 2483 // If there is a call target cache, mark it megamorphic in the |
2483 // non-function case. MegamorphicSentinel is an immortal immovable | 2484 // non-function case. MegamorphicSentinel is an immortal immovable |
2484 // object (undefined) so no write barrier is needed. | 2485 // object (megamorphic symbol) so no write barrier is needed. |
2485 __ mov(FieldOperand(ebx, edx, times_half_pointer_size, | 2486 __ mov(FieldOperand(ebx, edx, times_half_pointer_size, |
2486 FixedArray::kHeaderSize), | 2487 FixedArray::kHeaderSize), |
2487 Immediate(TypeFeedbackInfo::MegamorphicSentinel(isolate))); | 2488 Immediate(TypeFeedbackInfo::MegamorphicSentinel(isolate))); |
2488 } | 2489 } |
2489 // Check for function proxy. | 2490 // Check for function proxy. |
2490 __ CmpInstanceType(ecx, JS_FUNCTION_PROXY_TYPE); | 2491 __ CmpInstanceType(ecx, JS_FUNCTION_PROXY_TYPE); |
2491 __ j(not_equal, &non_function); | 2492 __ j(not_equal, &non_function); |
2492 __ pop(ecx); | 2493 __ pop(ecx); |
2493 __ push(edi); // put proxy as additional argument under return address | 2494 __ push(edi); // put proxy as additional argument under return address |
2494 __ push(ecx); | 2495 __ push(ecx); |
(...skipping 27 matching lines...) Expand all Loading... |
2522 } | 2523 } |
2523 __ mov(Operand(esp, (argc_ + 1) * kPointerSize), eax); | 2524 __ mov(Operand(esp, (argc_ + 1) * kPointerSize), eax); |
2524 __ jmp(&cont); | 2525 __ jmp(&cont); |
2525 } | 2526 } |
2526 } | 2527 } |
2527 | 2528 |
2528 | 2529 |
2529 void CallConstructStub::Generate(MacroAssembler* masm) { | 2530 void CallConstructStub::Generate(MacroAssembler* masm) { |
2530 // eax : number of arguments | 2531 // eax : number of arguments |
2531 // ebx : feedback vector | 2532 // ebx : feedback vector |
2532 // edx : (only if ebx is not undefined) slot in feedback vector (Smi) | 2533 // edx : (only if ebx is not the megamorphic symbol) slot in feedback |
| 2534 // vector (Smi) |
2533 // edi : constructor function | 2535 // edi : constructor function |
2534 Label slow, non_function_call; | 2536 Label slow, non_function_call; |
2535 | 2537 |
2536 // Check that function is not a smi. | 2538 // Check that function is not a smi. |
2537 __ JumpIfSmi(edi, &non_function_call); | 2539 __ JumpIfSmi(edi, &non_function_call); |
2538 // Check that function is a JSFunction. | 2540 // Check that function is a JSFunction. |
2539 __ CmpObjectType(edi, JS_FUNCTION_TYPE, ecx); | 2541 __ CmpObjectType(edi, JS_FUNCTION_TYPE, ecx); |
2540 __ j(not_equal, &slow); | 2542 __ j(not_equal, &slow); |
2541 | 2543 |
2542 if (RecordCallTarget()) { | 2544 if (RecordCallTarget()) { |
(...skipping 2602 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5145 CreateArrayDispatch<ArrayNArgumentsConstructorStub>(masm, mode); | 5147 CreateArrayDispatch<ArrayNArgumentsConstructorStub>(masm, mode); |
5146 } else { | 5148 } else { |
5147 UNREACHABLE(); | 5149 UNREACHABLE(); |
5148 } | 5150 } |
5149 } | 5151 } |
5150 | 5152 |
5151 | 5153 |
5152 void ArrayConstructorStub::Generate(MacroAssembler* masm) { | 5154 void ArrayConstructorStub::Generate(MacroAssembler* masm) { |
5153 // ----------- S t a t e ------------- | 5155 // ----------- S t a t e ------------- |
5154 // -- eax : argc (only if argument_count_ == ANY) | 5156 // -- eax : argc (only if argument_count_ == ANY) |
5155 // -- ebx : feedback vector (fixed array or undefined) | 5157 // -- ebx : feedback vector (fixed array or megamorphic symbol) |
5156 // -- edx : slot index (if ebx is fixed array) | 5158 // -- edx : slot index (if ebx is fixed array) |
5157 // -- edi : constructor | 5159 // -- edi : constructor |
5158 // -- esp[0] : return address | 5160 // -- esp[0] : return address |
5159 // -- esp[4] : last argument | 5161 // -- esp[4] : last argument |
5160 // ----------------------------------- | 5162 // ----------------------------------- |
5161 Handle<Object> undefined_sentinel( | 5163 Handle<Object> megamorphic_sentinel = |
5162 masm->isolate()->heap()->undefined_value(), | 5164 TypeFeedbackInfo::MegamorphicSentinel(masm->isolate()); |
5163 masm->isolate()); | |
5164 | 5165 |
5165 if (FLAG_debug_code) { | 5166 if (FLAG_debug_code) { |
5166 // The array construct code is only set for the global and natives | 5167 // The array construct code is only set for the global and natives |
5167 // builtin Array functions which always have maps. | 5168 // builtin Array functions which always have maps. |
5168 | 5169 |
5169 // Initial map for the builtin Array function should be a map. | 5170 // Initial map for the builtin Array function should be a map. |
5170 __ mov(ecx, FieldOperand(edi, JSFunction::kPrototypeOrInitialMapOffset)); | 5171 __ mov(ecx, FieldOperand(edi, JSFunction::kPrototypeOrInitialMapOffset)); |
5171 // Will both indicate a NULL and a Smi. | 5172 // Will both indicate a NULL and a Smi. |
5172 __ test(ecx, Immediate(kSmiTagMask)); | 5173 __ test(ecx, Immediate(kSmiTagMask)); |
5173 __ Assert(not_zero, kUnexpectedInitialMapForArrayFunction); | 5174 __ Assert(not_zero, kUnexpectedInitialMapForArrayFunction); |
5174 __ CmpObjectType(ecx, MAP_TYPE, ecx); | 5175 __ CmpObjectType(ecx, MAP_TYPE, ecx); |
5175 __ Assert(equal, kUnexpectedInitialMapForArrayFunction); | 5176 __ Assert(equal, kUnexpectedInitialMapForArrayFunction); |
5176 | 5177 |
5177 // We should either have undefined in ebx or a valid fixed array. | 5178 // We should either have the megamorphic symbol in ebx or a valid |
| 5179 // fixed array. |
5178 Label okay_here; | 5180 Label okay_here; |
5179 Handle<Map> fixed_array_map = masm->isolate()->factory()->fixed_array_map(); | 5181 Handle<Map> fixed_array_map = masm->isolate()->factory()->fixed_array_map(); |
5180 __ cmp(ebx, Immediate(undefined_sentinel)); | 5182 __ cmp(ebx, Immediate(megamorphic_sentinel)); |
5181 __ j(equal, &okay_here); | 5183 __ j(equal, &okay_here); |
5182 __ cmp(FieldOperand(ebx, 0), Immediate(fixed_array_map)); | 5184 __ cmp(FieldOperand(ebx, 0), Immediate(fixed_array_map)); |
5183 __ Assert(equal, kExpectedFixedArrayInRegisterEbx); | 5185 __ Assert(equal, kExpectedFixedArrayInRegisterEbx); |
5184 | 5186 |
5185 // edx should be a smi if we don't have undefined in ebx. | 5187 // edx should be a smi if we don't have the megamorphic symbol in ebx. |
5186 __ AssertSmi(edx); | 5188 __ AssertSmi(edx); |
5187 | 5189 |
5188 __ bind(&okay_here); | 5190 __ bind(&okay_here); |
5189 } | 5191 } |
5190 | 5192 |
5191 Label no_info; | 5193 Label no_info; |
5192 // If the feedback vector is undefined, or contains anything other than an | 5194 // If the feedback vector is the megamorphic sentinel, or contains anything |
5193 // AllocationSite, call an array constructor that doesn't use AllocationSites. | 5195 // other than an AllocationSite, call an array constructor that doesn't use |
5194 __ cmp(ebx, Immediate(undefined_sentinel)); | 5196 // AllocationSites. |
| 5197 __ cmp(ebx, Immediate(megamorphic_sentinel)); |
5195 __ j(equal, &no_info); | 5198 __ j(equal, &no_info); |
5196 __ mov(ebx, FieldOperand(ebx, edx, times_half_pointer_size, | 5199 __ mov(ebx, FieldOperand(ebx, edx, times_half_pointer_size, |
5197 FixedArray::kHeaderSize)); | 5200 FixedArray::kHeaderSize)); |
5198 __ cmp(FieldOperand(ebx, 0), Immediate( | 5201 __ cmp(FieldOperand(ebx, 0), Immediate( |
5199 masm->isolate()->factory()->allocation_site_map())); | 5202 masm->isolate()->factory()->allocation_site_map())); |
5200 __ j(not_equal, &no_info); | 5203 __ j(not_equal, &no_info); |
5201 | 5204 |
5202 // Only look at the lower 16 bits of the transition info. | 5205 // Only look at the lower 16 bits of the transition info. |
5203 __ mov(edx, FieldOperand(ebx, AllocationSite::kTransitionInfoOffset)); | 5206 __ mov(edx, FieldOperand(ebx, AllocationSite::kTransitionInfoOffset)); |
5204 __ SmiUntag(edx); | 5207 __ SmiUntag(edx); |
(...skipping 250 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5455 Operand(ebp, 7 * kPointerSize), | 5458 Operand(ebp, 7 * kPointerSize), |
5456 NULL); | 5459 NULL); |
5457 } | 5460 } |
5458 | 5461 |
5459 | 5462 |
5460 #undef __ | 5463 #undef __ |
5461 | 5464 |
5462 } } // namespace v8::internal | 5465 } } // namespace v8::internal |
5463 | 5466 |
5464 #endif // V8_TARGET_ARCH_IA32 | 5467 #endif // V8_TARGET_ARCH_IA32 |
OLD | NEW |