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