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