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 2356 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2367 if (NeedsChecks()) { | 2367 if (NeedsChecks()) { |
2368 // Check that the function really is a JavaScript function. | 2368 // Check that the function really is a JavaScript function. |
2369 __ JumpIfSmi(edi, &non_function); | 2369 __ JumpIfSmi(edi, &non_function); |
2370 | 2370 |
2371 // Goto slow case if we do not have a function. | 2371 // Goto slow case if we do not have a function. |
2372 __ CmpObjectType(edi, JS_FUNCTION_TYPE, ecx); | 2372 __ CmpObjectType(edi, JS_FUNCTION_TYPE, ecx); |
2373 __ j(not_equal, &slow); | 2373 __ j(not_equal, &slow); |
2374 | 2374 |
2375 if (RecordCallTarget()) { | 2375 if (RecordCallTarget()) { |
2376 GenerateRecordCallTarget(masm); | 2376 GenerateRecordCallTarget(masm); |
| 2377 // Type information was updated. Because we may call Array, which |
| 2378 // expects either undefined or an AllocationSite in ebx we need |
| 2379 // to set ebx to undefined. |
| 2380 __ mov(ebx, Immediate(isolate->factory()->undefined_value())); |
2377 } | 2381 } |
2378 } | 2382 } |
2379 | 2383 |
2380 // Fast-case: Just invoke the function. | 2384 // Fast-case: Just invoke the function. |
2381 ParameterCount actual(argc_); | 2385 ParameterCount actual(argc_); |
2382 | 2386 |
2383 if (CallAsMethod()) { | 2387 if (CallAsMethod()) { |
2384 if (NeedsChecks()) { | 2388 if (NeedsChecks()) { |
2385 // Do not transform the receiver for strict mode functions. | 2389 // Do not transform the receiver for strict mode functions. |
2386 __ mov(ecx, FieldOperand(edi, JSFunction::kSharedFunctionInfoOffset)); | 2390 __ mov(ecx, FieldOperand(edi, JSFunction::kSharedFunctionInfoOffset)); |
(...skipping 83 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2470 // edi : constructor function | 2474 // edi : constructor function |
2471 Label slow, non_function_call; | 2475 Label slow, non_function_call; |
2472 | 2476 |
2473 // Check that function is not a smi. | 2477 // Check that function is not a smi. |
2474 __ JumpIfSmi(edi, &non_function_call); | 2478 __ JumpIfSmi(edi, &non_function_call); |
2475 // Check that function is a JSFunction. | 2479 // Check that function is a JSFunction. |
2476 __ CmpObjectType(edi, JS_FUNCTION_TYPE, ecx); | 2480 __ CmpObjectType(edi, JS_FUNCTION_TYPE, ecx); |
2477 __ j(not_equal, &slow); | 2481 __ j(not_equal, &slow); |
2478 | 2482 |
2479 if (RecordCallTarget()) { | 2483 if (RecordCallTarget()) { |
| 2484 Label feedback_register_initialized; |
2480 GenerateRecordCallTarget(masm); | 2485 GenerateRecordCallTarget(masm); |
| 2486 |
| 2487 // Put the AllocationSite from the feedback vector into ebx, or undefined. |
| 2488 __ mov(ebx, FieldOperand(ebx, edx, times_half_pointer_size, |
| 2489 FixedArray::kHeaderSize)); |
| 2490 Handle<Map> allocation_site_map = |
| 2491 masm->isolate()->factory()->allocation_site_map(); |
| 2492 __ cmp(FieldOperand(ebx, 0), Immediate(allocation_site_map)); |
| 2493 __ j(equal, &feedback_register_initialized); |
| 2494 __ mov(ebx, masm->isolate()->factory()->undefined_value()); |
| 2495 __ bind(&feedback_register_initialized); |
| 2496 __ AssertUndefinedOrAllocationSite(ebx); |
2481 } | 2497 } |
2482 | 2498 |
2483 // Jump to the function-specific construct stub. | 2499 // Jump to the function-specific construct stub. |
2484 Register jmp_reg = ecx; | 2500 Register jmp_reg = ecx; |
2485 __ mov(jmp_reg, FieldOperand(edi, JSFunction::kSharedFunctionInfoOffset)); | 2501 __ mov(jmp_reg, FieldOperand(edi, JSFunction::kSharedFunctionInfoOffset)); |
2486 __ mov(jmp_reg, FieldOperand(jmp_reg, | 2502 __ mov(jmp_reg, FieldOperand(jmp_reg, |
2487 SharedFunctionInfo::kConstructStubOffset)); | 2503 SharedFunctionInfo::kConstructStubOffset)); |
2488 __ lea(jmp_reg, FieldOperand(jmp_reg, Code::kHeaderSize)); | 2504 __ lea(jmp_reg, FieldOperand(jmp_reg, Code::kHeaderSize)); |
2489 __ jmp(jmp_reg); | 2505 __ jmp(jmp_reg); |
2490 | 2506 |
(...skipping 2584 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5075 CreateArrayDispatch<ArrayNArgumentsConstructorStub>(masm, mode); | 5091 CreateArrayDispatch<ArrayNArgumentsConstructorStub>(masm, mode); |
5076 } else { | 5092 } else { |
5077 UNREACHABLE(); | 5093 UNREACHABLE(); |
5078 } | 5094 } |
5079 } | 5095 } |
5080 | 5096 |
5081 | 5097 |
5082 void ArrayConstructorStub::Generate(MacroAssembler* masm) { | 5098 void ArrayConstructorStub::Generate(MacroAssembler* masm) { |
5083 // ----------- S t a t e ------------- | 5099 // ----------- S t a t e ------------- |
5084 // -- eax : argc (only if argument_count_ == ANY) | 5100 // -- eax : argc (only if argument_count_ == ANY) |
5085 // -- ebx : feedback vector (fixed array or megamorphic symbol) | 5101 // -- ebx : AllocationSite or undefined |
5086 // -- edx : slot index (if ebx is fixed array) | |
5087 // -- edi : constructor | 5102 // -- edi : constructor |
5088 // -- esp[0] : return address | 5103 // -- esp[0] : return address |
5089 // -- esp[4] : last argument | 5104 // -- esp[4] : last argument |
5090 // ----------------------------------- | 5105 // ----------------------------------- |
5091 Handle<Object> megamorphic_sentinel = | |
5092 TypeFeedbackInfo::MegamorphicSentinel(masm->isolate()); | |
5093 | |
5094 if (FLAG_debug_code) { | 5106 if (FLAG_debug_code) { |
5095 // The array construct code is only set for the global and natives | 5107 // The array construct code is only set for the global and natives |
5096 // builtin Array functions which always have maps. | 5108 // builtin Array functions which always have maps. |
5097 | 5109 |
5098 // Initial map for the builtin Array function should be a map. | 5110 // Initial map for the builtin Array function should be a map. |
5099 __ mov(ecx, FieldOperand(edi, JSFunction::kPrototypeOrInitialMapOffset)); | 5111 __ mov(ecx, FieldOperand(edi, JSFunction::kPrototypeOrInitialMapOffset)); |
5100 // Will both indicate a NULL and a Smi. | 5112 // Will both indicate a NULL and a Smi. |
5101 __ test(ecx, Immediate(kSmiTagMask)); | 5113 __ test(ecx, Immediate(kSmiTagMask)); |
5102 __ Assert(not_zero, kUnexpectedInitialMapForArrayFunction); | 5114 __ Assert(not_zero, kUnexpectedInitialMapForArrayFunction); |
5103 __ CmpObjectType(ecx, MAP_TYPE, ecx); | 5115 __ CmpObjectType(ecx, MAP_TYPE, ecx); |
5104 __ Assert(equal, kUnexpectedInitialMapForArrayFunction); | 5116 __ Assert(equal, kUnexpectedInitialMapForArrayFunction); |
5105 | 5117 |
5106 // We should either have the megamorphic symbol in ebx or a valid | 5118 // We should either have undefined in ebx or a valid AllocationSite |
5107 // fixed array. | 5119 __ AssertUndefinedOrAllocationSite(ebx); |
5108 Label okay_here; | |
5109 Handle<Map> fixed_array_map = masm->isolate()->factory()->fixed_array_map(); | |
5110 __ cmp(ebx, Immediate(megamorphic_sentinel)); | |
5111 __ j(equal, &okay_here); | |
5112 __ cmp(FieldOperand(ebx, 0), Immediate(fixed_array_map)); | |
5113 __ Assert(equal, kExpectedFixedArrayInRegisterEbx); | |
5114 | |
5115 // edx should be a smi if we don't have the megamorphic symbol in ebx. | |
5116 __ AssertSmi(edx); | |
5117 | |
5118 __ bind(&okay_here); | |
5119 } | 5120 } |
5120 | 5121 |
5121 Label no_info; | 5122 Label no_info; |
5122 // If the feedback vector is the megamorphic sentinel, or contains anything | 5123 // If the feedback vector is the undefined value call an array constructor |
5123 // other than an AllocationSite, call an array constructor that doesn't use | 5124 // that doesn't use AllocationSites. |
5124 // AllocationSites. | 5125 __ cmp(ebx, masm->isolate()->factory()->undefined_value()); |
5125 __ cmp(ebx, Immediate(megamorphic_sentinel)); | |
5126 __ j(equal, &no_info); | 5126 __ j(equal, &no_info); |
5127 __ mov(ebx, FieldOperand(ebx, edx, times_half_pointer_size, | |
5128 FixedArray::kHeaderSize)); | |
5129 __ cmp(FieldOperand(ebx, 0), Immediate( | |
5130 masm->isolate()->factory()->allocation_site_map())); | |
5131 __ j(not_equal, &no_info); | |
5132 | 5127 |
5133 // Only look at the lower 16 bits of the transition info. | 5128 // Only look at the lower 16 bits of the transition info. |
5134 __ mov(edx, FieldOperand(ebx, AllocationSite::kTransitionInfoOffset)); | 5129 __ mov(edx, FieldOperand(ebx, AllocationSite::kTransitionInfoOffset)); |
5135 __ SmiUntag(edx); | 5130 __ SmiUntag(edx); |
5136 STATIC_ASSERT(AllocationSite::ElementsKindBits::kShift == 0); | 5131 STATIC_ASSERT(AllocationSite::ElementsKindBits::kShift == 0); |
5137 __ and_(edx, Immediate(AllocationSite::ElementsKindBits::kMask)); | 5132 __ and_(edx, Immediate(AllocationSite::ElementsKindBits::kMask)); |
5138 GenerateDispatchToArrayStub(masm, DONT_OVERRIDE); | 5133 GenerateDispatchToArrayStub(masm, DONT_OVERRIDE); |
5139 | 5134 |
5140 __ bind(&no_info); | 5135 __ bind(&no_info); |
5141 GenerateDispatchToArrayStub(masm, DISABLE_ALLOCATION_SITES); | 5136 GenerateDispatchToArrayStub(masm, DISABLE_ALLOCATION_SITES); |
(...skipping 244 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5386 Operand(ebp, 7 * kPointerSize), | 5381 Operand(ebp, 7 * kPointerSize), |
5387 NULL); | 5382 NULL); |
5388 } | 5383 } |
5389 | 5384 |
5390 | 5385 |
5391 #undef __ | 5386 #undef __ |
5392 | 5387 |
5393 } } // namespace v8::internal | 5388 } } // namespace v8::internal |
5394 | 5389 |
5395 #endif // V8_TARGET_ARCH_IA32 | 5390 #endif // V8_TARGET_ARCH_IA32 |
OLD | NEW |