OLD | NEW |
1 // Copyright 2013 the V8 project authors. All rights reserved. | 1 // Copyright 2013 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 3288 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3299 | 3299 |
3300 if (NeedsChecks()) { | 3300 if (NeedsChecks()) { |
3301 // Check that the function is really a JavaScript function. | 3301 // Check that the function is really a JavaScript function. |
3302 __ JumpIfSmi(function, &non_function); | 3302 __ JumpIfSmi(function, &non_function); |
3303 | 3303 |
3304 // Goto slow case if we do not have a function. | 3304 // Goto slow case if we do not have a function. |
3305 __ JumpIfNotObjectType(function, x10, type, JS_FUNCTION_TYPE, &slow); | 3305 __ JumpIfNotObjectType(function, x10, type, JS_FUNCTION_TYPE, &slow); |
3306 | 3306 |
3307 if (RecordCallTarget()) { | 3307 if (RecordCallTarget()) { |
3308 GenerateRecordCallTarget(masm, x0, function, cache_cell, slot, x4, x5); | 3308 GenerateRecordCallTarget(masm, x0, function, cache_cell, slot, x4, x5); |
| 3309 // Type information was updated. Because we may call Array, which |
| 3310 // expects either undefined or an AllocationSite in ebx we need |
| 3311 // to set ebx to undefined. |
| 3312 __ LoadRoot(cache_cell, Heap::kUndefinedValueRootIndex); |
3309 } | 3313 } |
3310 } | 3314 } |
3311 | 3315 |
3312 // Fast-case: Invoke the function now. | 3316 // Fast-case: Invoke the function now. |
3313 // x1 function pushed function | 3317 // x1 function pushed function |
3314 ParameterCount actual(argc_); | 3318 ParameterCount actual(argc_); |
3315 | 3319 |
3316 if (CallAsMethod()) { | 3320 if (CallAsMethod()) { |
3317 if (NeedsChecks()) { | 3321 if (NeedsChecks()) { |
3318 // Do not transform the receiver for strict mode functions. | 3322 // Do not transform the receiver for strict mode functions. |
(...skipping 84 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3403 Label slow, non_function_call; | 3407 Label slow, non_function_call; |
3404 | 3408 |
3405 // Check that the function is not a smi. | 3409 // Check that the function is not a smi. |
3406 __ JumpIfSmi(function, &non_function_call); | 3410 __ JumpIfSmi(function, &non_function_call); |
3407 // Check that the function is a JSFunction. | 3411 // Check that the function is a JSFunction. |
3408 Register object_type = x10; | 3412 Register object_type = x10; |
3409 __ JumpIfNotObjectType(function, object_type, object_type, JS_FUNCTION_TYPE, | 3413 __ JumpIfNotObjectType(function, object_type, object_type, JS_FUNCTION_TYPE, |
3410 &slow); | 3414 &slow); |
3411 | 3415 |
3412 if (RecordCallTarget()) { | 3416 if (RecordCallTarget()) { |
| 3417 Label feedback_register_initialized; |
3413 GenerateRecordCallTarget(masm, x0, function, x2, x3, x4, x5); | 3418 GenerateRecordCallTarget(masm, x0, function, x2, x3, x4, x5); |
| 3419 |
| 3420 // Put the AllocationSite from the feedback vector into x2, or undefined. |
| 3421 __ Add(x5, x2, Operand::UntagSmiAndScale(x3, kPointerSizeLog2)); |
| 3422 __ Ldr(x2, FieldMemOperand(x5, FixedArray::kHeaderSize)); |
| 3423 __ Ldr(x5, FieldMemOperand(x2, AllocationSite::kMapOffset)); |
| 3424 __ JumpIfRoot(x5, Heap::kAllocationSiteMapRootIndex, |
| 3425 &feedback_register_initialized); |
| 3426 __ LoadRoot(x2, Heap::kUndefinedValueRootIndex); |
| 3427 __ bind(&feedback_register_initialized); |
| 3428 __ AssertUndefinedOrAllocationSite(x2, x5); |
3414 } | 3429 } |
3415 | 3430 |
3416 // Jump to the function-specific construct stub. | 3431 // Jump to the function-specific construct stub. |
3417 Register jump_reg = x4; | 3432 Register jump_reg = x4; |
3418 Register shared_func_info = jump_reg; | 3433 Register shared_func_info = jump_reg; |
3419 Register cons_stub = jump_reg; | 3434 Register cons_stub = jump_reg; |
3420 Register cons_stub_code = jump_reg; | 3435 Register cons_stub_code = jump_reg; |
3421 __ Ldr(shared_func_info, | 3436 __ Ldr(shared_func_info, |
3422 FieldMemOperand(function, JSFunction::kSharedFunctionInfoOffset)); | 3437 FieldMemOperand(function, JSFunction::kSharedFunctionInfoOffset)); |
3423 __ Ldr(cons_stub, | 3438 __ Ldr(cons_stub, |
(...skipping 1974 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5398 UNREACHABLE(); | 5413 UNREACHABLE(); |
5399 } | 5414 } |
5400 } | 5415 } |
5401 | 5416 |
5402 | 5417 |
5403 void ArrayConstructorStub::Generate(MacroAssembler* masm) { | 5418 void ArrayConstructorStub::Generate(MacroAssembler* masm) { |
5404 ASM_LOCATION("ArrayConstructorStub::Generate"); | 5419 ASM_LOCATION("ArrayConstructorStub::Generate"); |
5405 // ----------- S t a t e ------------- | 5420 // ----------- S t a t e ------------- |
5406 // -- x0 : argc (only if argument_count_ == ANY) | 5421 // -- x0 : argc (only if argument_count_ == ANY) |
5407 // -- x1 : constructor | 5422 // -- x1 : constructor |
5408 // -- x2 : feedback vector (fixed array or the megamorphic symbol) | 5423 // -- x2 : AllocationSite or undefined |
5409 // -- x3 : slot index (if x2 is fixed array) | |
5410 // -- sp[0] : return address | 5424 // -- sp[0] : return address |
5411 // -- sp[4] : last argument | 5425 // -- sp[4] : last argument |
5412 // ----------------------------------- | 5426 // ----------------------------------- |
5413 Register constructor = x1; | 5427 Register constructor = x1; |
5414 Register feedback_vector = x2; | 5428 Register allocation_site = x2; |
5415 Register slot_index = x3; | |
5416 | |
5417 ASSERT_EQ(*TypeFeedbackInfo::MegamorphicSentinel(masm->isolate()), | |
5418 masm->isolate()->heap()->megamorphic_symbol()); | |
5419 | 5429 |
5420 if (FLAG_debug_code) { | 5430 if (FLAG_debug_code) { |
5421 // The array construct code is only set for the global and natives | 5431 // The array construct code is only set for the global and natives |
5422 // builtin Array functions which always have maps. | 5432 // builtin Array functions which always have maps. |
5423 | 5433 |
5424 Label unexpected_map, map_ok; | 5434 Label unexpected_map, map_ok; |
5425 // Initial map for the builtin Array function should be a map. | 5435 // Initial map for the builtin Array function should be a map. |
5426 __ Ldr(x10, FieldMemOperand(constructor, | 5436 __ Ldr(x10, FieldMemOperand(constructor, |
5427 JSFunction::kPrototypeOrInitialMapOffset)); | 5437 JSFunction::kPrototypeOrInitialMapOffset)); |
5428 // Will both indicate a NULL and a Smi. | 5438 // Will both indicate a NULL and a Smi. |
5429 __ JumpIfSmi(x10, &unexpected_map); | 5439 __ JumpIfSmi(x10, &unexpected_map); |
5430 __ JumpIfObjectType(x10, x10, x11, MAP_TYPE, &map_ok); | 5440 __ JumpIfObjectType(x10, x10, x11, MAP_TYPE, &map_ok); |
5431 __ Bind(&unexpected_map); | 5441 __ Bind(&unexpected_map); |
5432 __ Abort(kUnexpectedInitialMapForArrayFunction); | 5442 __ Abort(kUnexpectedInitialMapForArrayFunction); |
5433 __ Bind(&map_ok); | 5443 __ Bind(&map_ok); |
5434 | 5444 |
5435 // In feedback_vector, we expect either the megamorphic symbol or a valid | 5445 // We should either have undefined in the allocation_site register or a |
5436 // fixed array. | 5446 // valid AllocationSite. |
5437 Label okay_here; | 5447 __ AssertUndefinedOrAllocationSite(allocation_site, x10); |
5438 Handle<Map> fixed_array_map = masm->isolate()->factory()->fixed_array_map(); | |
5439 __ JumpIfRoot(feedback_vector, Heap::kMegamorphicSymbolRootIndex, | |
5440 &okay_here); | |
5441 __ Ldr(x10, FieldMemOperand(feedback_vector, FixedArray::kMapOffset)); | |
5442 __ Cmp(x10, Operand(fixed_array_map)); | |
5443 __ Assert(eq, kExpectedFixedArrayInFeedbackVector); | |
5444 | |
5445 // slot_index should be a smi if we don't have undefined in feedback_vector. | |
5446 __ AssertSmi(slot_index); | |
5447 | |
5448 __ Bind(&okay_here); | |
5449 } | 5448 } |
5450 | 5449 |
5451 Register allocation_site = x2; // Overwrites feedback_vector. | |
5452 Register kind = x3; | 5450 Register kind = x3; |
5453 Label no_info; | 5451 Label no_info; |
5454 // Get the elements kind and case on that. | 5452 // Get the elements kind and case on that. |
5455 __ JumpIfRoot(feedback_vector, Heap::kMegamorphicSymbolRootIndex, &no_info); | 5453 __ JumpIfRoot(allocation_site, Heap::kUndefinedValueRootIndex, &no_info); |
5456 __ Add(feedback_vector, feedback_vector, | |
5457 Operand::UntagSmiAndScale(slot_index, kPointerSizeLog2)); | |
5458 __ Ldr(allocation_site, FieldMemOperand(feedback_vector, | |
5459 FixedArray::kHeaderSize)); | |
5460 | |
5461 // If the feedback vector is the megamorphic symbol, or contains anything | |
5462 // other than an AllocationSite, call an array constructor that doesn't | |
5463 // use AllocationSites. | |
5464 __ Ldr(x10, FieldMemOperand(allocation_site, AllocationSite::kMapOffset)); | |
5465 __ JumpIfNotRoot(x10, Heap::kAllocationSiteMapRootIndex, &no_info); | |
5466 | 5454 |
5467 __ Ldrsw(kind, | 5455 __ Ldrsw(kind, |
5468 UntagSmiFieldMemOperand(allocation_site, | 5456 UntagSmiFieldMemOperand(allocation_site, |
5469 AllocationSite::kTransitionInfoOffset)); | 5457 AllocationSite::kTransitionInfoOffset)); |
5470 __ And(kind, kind, AllocationSite::ElementsKindBits::kMask); | 5458 __ And(kind, kind, AllocationSite::ElementsKindBits::kMask); |
5471 GenerateDispatchToArrayStub(masm, DONT_OVERRIDE); | 5459 GenerateDispatchToArrayStub(masm, DONT_OVERRIDE); |
5472 | 5460 |
5473 __ Bind(&no_info); | 5461 __ Bind(&no_info); |
5474 GenerateDispatchToArrayStub(masm, DISABLE_ALLOCATION_SITES); | 5462 GenerateDispatchToArrayStub(masm, DISABLE_ALLOCATION_SITES); |
5475 } | 5463 } |
(...skipping 246 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5722 MemOperand(fp, 6 * kPointerSize), | 5710 MemOperand(fp, 6 * kPointerSize), |
5723 NULL); | 5711 NULL); |
5724 } | 5712 } |
5725 | 5713 |
5726 | 5714 |
5727 #undef __ | 5715 #undef __ |
5728 | 5716 |
5729 } } // namespace v8::internal | 5717 } } // namespace v8::internal |
5730 | 5718 |
5731 #endif // V8_TARGET_ARCH_A64 | 5719 #endif // V8_TARGET_ARCH_A64 |
OLD | NEW |