Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(394)

Side by Side Diff: src/a64/code-stubs-a64.cc

Issue 141363005: A64: Synchronize with r15204. (Closed) Base URL: https://v8.googlecode.com/svn/branches/experimental/a64
Patch Set: Created 6 years, 11 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « src/a64/assembler-a64-inl.h ('k') | src/a64/full-codegen-a64.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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 4456 matching lines...) Expand 10 before | Expand all | Expand 10 after
4467 // x1 : the function to call 4467 // x1 : the function to call
4468 // x2 : cache cell for the call target 4468 // x2 : cache cell for the call target
4469 Label done; 4469 Label done;
4470 4470
4471 ASSERT_EQ(*TypeFeedbackCells::MegamorphicSentinel(masm->isolate()), 4471 ASSERT_EQ(*TypeFeedbackCells::MegamorphicSentinel(masm->isolate()),
4472 masm->isolate()->heap()->undefined_value()); 4472 masm->isolate()->heap()->undefined_value());
4473 ASSERT_EQ(*TypeFeedbackCells::UninitializedSentinel(masm->isolate()), 4473 ASSERT_EQ(*TypeFeedbackCells::UninitializedSentinel(masm->isolate()),
4474 masm->isolate()->heap()->the_hole_value()); 4474 masm->isolate()->heap()->the_hole_value());
4475 4475
4476 // Load the cache state. 4476 // Load the cache state.
4477 __ Ldr(x3, FieldMemOperand(x2, JSGlobalPropertyCell::kValueOffset)); 4477 __ Ldr(x3, FieldMemOperand(x2, Cell::kValueOffset));
4478 4478
4479 // A monomorphic cache hit or an already megamorphic state: invoke the 4479 // A monomorphic cache hit or an already megamorphic state: invoke the
4480 // function without changing the state. 4480 // function without changing the state.
4481 __ Cmp(x3, x1); 4481 __ Cmp(x3, x1);
4482 __ B(eq, &done); 4482 __ B(eq, &done);
4483 __ JumpIfRoot(x3, Heap::kUndefinedValueRootIndex, &done); 4483 __ JumpIfRoot(x3, Heap::kUndefinedValueRootIndex, &done);
4484 4484
4485 // A monomorphic miss (i.e, here the cache is not uninitialized) goes 4485 // A monomorphic miss (i.e, here the cache is not uninitialized) goes
4486 // megamorphic. MegamorphicSentinal is an immortal immovable object 4486 // megamorphic. MegamorphicSentinal is an immortal immovable object
4487 // (undefined) so no write-barrier is needed. 4487 // (undefined) so no write-barrier is needed.
4488 Label skip_undef_store; 4488 Label skip_undef_store;
4489 __ JumpIfRoot(x3, Heap::kTheHoleValueRootIndex, &skip_undef_store); 4489 __ JumpIfRoot(x3, Heap::kTheHoleValueRootIndex, &skip_undef_store);
4490 __ LoadRoot(ip0, Heap::kUndefinedValueRootIndex); 4490 __ LoadRoot(ip0, Heap::kUndefinedValueRootIndex);
4491 __ Str(ip0, FieldMemOperand(x2, JSGlobalPropertyCell::kValueOffset)); 4491 __ Str(ip0, FieldMemOperand(x2, Cell::kValueOffset));
4492 __ B(&done); 4492 __ B(&done);
4493 __ Bind(&skip_undef_store); 4493 __ Bind(&skip_undef_store);
4494 4494
4495 // An uninitialized cache is patched with the function. 4495 // An uninitialized cache is patched with the function.
4496 __ Str(x1, FieldMemOperand(x2, JSGlobalPropertyCell::kValueOffset)); 4496 __ Str(x1, FieldMemOperand(x2, Cell::kValueOffset));
4497 // No need for a write barrier here - cells are rescanned. 4497 // No need for a write barrier here - cells are rescanned.
4498 4498
4499 __ Bind(&done); 4499 __ Bind(&done);
4500 } 4500 }
4501 4501
4502 4502
4503 // TODO(jbramley): Don't use static registers here, but take them as arguments. 4503 // TODO(jbramley): Don't use static registers here, but take them as arguments.
4504 static void GenerateRecordCallTarget(MacroAssembler* masm) { 4504 static void GenerateRecordCallTarget(MacroAssembler* masm) {
4505 // Cache the called function in a global property cell. Cache states are 4505 // Cache the called function in a global property cell. Cache states are
4506 // uninitialized, monomorphic (indicated by a JSFunction), and megamorphic. 4506 // uninitialized, monomorphic (indicated by a JSFunction), and megamorphic.
4507 // x1 : the function to call 4507 // x1 : the function to call
4508 // x2 : cache cell for the call target 4508 // x2 : cache cell for the call target
4509 ASSERT(FLAG_optimize_constructed_arrays); 4509 ASSERT(FLAG_optimize_constructed_arrays);
4510 Label initialize, done, miss, megamorphic, not_array_function; 4510 Label initialize, done, miss, megamorphic, not_array_function;
4511 4511
4512 ASSERT_EQ(*TypeFeedbackCells::MegamorphicSentinel(masm->isolate()), 4512 ASSERT_EQ(*TypeFeedbackCells::MegamorphicSentinel(masm->isolate()),
4513 masm->isolate()->heap()->undefined_value()); 4513 masm->isolate()->heap()->undefined_value());
4514 ASSERT_EQ(*TypeFeedbackCells::UninitializedSentinel(masm->isolate()), 4514 ASSERT_EQ(*TypeFeedbackCells::UninitializedSentinel(masm->isolate()),
4515 masm->isolate()->heap()->the_hole_value()); 4515 masm->isolate()->heap()->the_hole_value());
4516 4516
4517 // Load the cache state. 4517 // Load the cache state.
4518 __ Ldr(x3, FieldMemOperand(x2, JSGlobalPropertyCell::kValueOffset)); 4518 __ Ldr(x3, FieldMemOperand(x2, Cell::kValueOffset));
4519 4519
4520 // A monomorphic cache hit or an already megamorphic state: invoke the 4520 // A monomorphic cache hit or an already megamorphic state: invoke the
4521 // function without changing the state. 4521 // function without changing the state.
4522 __ Cmp(x3, x1); 4522 __ Cmp(x3, x1);
4523 __ B(eq, &done); 4523 __ B(eq, &done);
4524 __ JumpIfRoot(x3, Heap::kUndefinedValueRootIndex, &done); 4524 __ JumpIfRoot(x3, Heap::kUndefinedValueRootIndex, &done);
4525 4525
4526 // Special handling of the Array() function, which caches not only the 4526 // Special handling of the Array() function, which caches not only the
4527 // monomorphic Array function but the initial ElementsKind with special 4527 // monomorphic Array function but the initial ElementsKind with special
4528 // sentinels 4528 // sentinels
(...skipping 11 matching lines...) Expand all
4540 4540
4541 __ Bind(&miss); 4541 __ Bind(&miss);
4542 4542
4543 // A monomorphic miss (i.e, here the cache is not uninitialized) goes 4543 // A monomorphic miss (i.e, here the cache is not uninitialized) goes
4544 // megamorphic. 4544 // megamorphic.
4545 __ JumpIfRoot(x3, Heap::kTheHoleValueRootIndex, &initialize); 4545 __ JumpIfRoot(x3, Heap::kTheHoleValueRootIndex, &initialize);
4546 // MegamorphicSentinel is an immortal immovable object (undefined) so no 4546 // MegamorphicSentinel is an immortal immovable object (undefined) so no
4547 // write-barrier is needed. 4547 // write-barrier is needed.
4548 __ Bind(&megamorphic); 4548 __ Bind(&megamorphic);
4549 __ LoadRoot(x3, Heap::kUndefinedValueRootIndex); 4549 __ LoadRoot(x3, Heap::kUndefinedValueRootIndex);
4550 __ Str(x3, FieldMemOperand(x2, JSGlobalPropertyCell::kValueOffset)); 4550 __ Str(x3, FieldMemOperand(x2, Cell::kValueOffset));
4551 __ B(&done); 4551 __ B(&done);
4552 4552
4553 // An uninitialized cache is patched with the function or sentinel to 4553 // An uninitialized cache is patched with the function or sentinel to
4554 // indicate the ElementsKind if function is the Array constructor. 4554 // indicate the ElementsKind if function is the Array constructor.
4555 __ Bind(&initialize); 4555 __ Bind(&initialize);
4556 // Make sure the function is the Array() function 4556 // Make sure the function is the Array() function
4557 __ LoadArrayFunction(x3); 4557 __ LoadArrayFunction(x3);
4558 __ Cmp(x1, x3); 4558 __ Cmp(x1, x3);
4559 __ B(ne, &not_array_function); 4559 __ B(ne, &not_array_function);
4560 4560
4561 // The target function is the Array constructor, install a sentinel value in 4561 // The target function is the Array constructor, install a sentinel value in
4562 // the constructor's type info cell that will track the initial ElementsKind 4562 // the constructor's type info cell that will track the initial ElementsKind
4563 // that should be used for the array when its constructed. 4563 // that should be used for the array when its constructed.
4564 Handle<Object> initial_kind_sentinel = 4564 Handle<Object> initial_kind_sentinel =
4565 TypeFeedbackCells::MonomorphicArraySentinel(masm->isolate(), 4565 TypeFeedbackCells::MonomorphicArraySentinel(masm->isolate(),
4566 GetInitialFastElementsKind()); 4566 GetInitialFastElementsKind());
4567 __ Mov(x3, Operand(initial_kind_sentinel)); 4567 __ Mov(x3, Operand(initial_kind_sentinel));
4568 __ Str(x3, FieldMemOperand(x2, JSGlobalPropertyCell::kValueOffset)); 4568 __ Str(x3, FieldMemOperand(x2, Cell::kValueOffset));
4569 __ B(&done); 4569 __ B(&done);
4570 4570
4571 __ Bind(&not_array_function); 4571 __ Bind(&not_array_function);
4572 // An uninitialized cache is patched with the function. 4572 // An uninitialized cache is patched with the function.
4573 __ Str(x1, FieldMemOperand(x2, JSGlobalPropertyCell::kValueOffset)); 4573 __ Str(x1, FieldMemOperand(x2, Cell::kValueOffset));
4574 // No need for a write barrier here - cells are rescanned. 4574 // No need for a write barrier here - cells are rescanned.
4575 4575
4576 __ Bind(&done); 4576 __ Bind(&done);
4577 } 4577 }
4578 4578
4579 4579
4580 void CallFunctionStub::Generate(MacroAssembler* masm) { 4580 void CallFunctionStub::Generate(MacroAssembler* masm) {
4581 ASM_LOCATION("CallFunctionStub::Generate"); 4581 ASM_LOCATION("CallFunctionStub::Generate");
4582 // x1 function the function to call 4582 // x1 function the function to call
4583 // x2 cache_cell cache cell for call target 4583 // x2 cache_cell cache cell for call target
(...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after
4640 4640
4641 // Slow-case: Non-function called. 4641 // Slow-case: Non-function called.
4642 __ Bind(&slow); 4642 __ Bind(&slow);
4643 if (RecordCallTarget()) { 4643 if (RecordCallTarget()) {
4644 // If there is a call target cache, mark it megamorphic in the 4644 // If there is a call target cache, mark it megamorphic in the
4645 // non-function case. MegamorphicSentinel is an immortal immovable object 4645 // non-function case. MegamorphicSentinel is an immortal immovable object
4646 // (undefined) so no write barrier is needed. 4646 // (undefined) so no write barrier is needed.
4647 ASSERT_EQ(*TypeFeedbackCells::MegamorphicSentinel(masm->isolate()), 4647 ASSERT_EQ(*TypeFeedbackCells::MegamorphicSentinel(masm->isolate()),
4648 masm->isolate()->heap()->undefined_value()); 4648 masm->isolate()->heap()->undefined_value());
4649 __ LoadRoot(x11, Heap::kUndefinedValueRootIndex); 4649 __ LoadRoot(x11, Heap::kUndefinedValueRootIndex);
4650 __ Str(x11, FieldMemOperand(cache_cell, 4650 __ Str(x11, FieldMemOperand(cache_cell, Cell::kValueOffset));
4651 JSGlobalPropertyCell::kValueOffset));
4652 } 4651 }
4653 // Check for function proxy. 4652 // Check for function proxy.
4654 // x10 : function type. 4653 // x10 : function type.
4655 __ Cmp(x10, JS_FUNCTION_PROXY_TYPE); 4654 __ Cmp(x10, JS_FUNCTION_PROXY_TYPE);
4656 __ B(ne, &non_function); 4655 __ B(ne, &non_function);
4657 __ Push(function); // put proxy as additional argument 4656 __ Push(function); // put proxy as additional argument
4658 __ Mov(x0, argc_ + 1); 4657 __ Mov(x0, argc_ + 1);
4659 __ Mov(x2, 0); 4658 __ Mov(x2, 0);
4660 __ GetBuiltinEntry(x3, Builtins::CALL_FUNCTION_PROXY); 4659 __ GetBuiltinEntry(x3, Builtins::CALL_FUNCTION_PROXY);
4661 __ SetCallKind(x5, CALL_AS_METHOD); 4660 __ SetCallKind(x5, CALL_AS_METHOD);
(...skipping 1932 matching lines...) Expand 10 before | Expand all | Expand 10 after
6594 } 6593 }
6595 6594
6596 6595
6597 void StoreArrayLiteralElementStub::Generate(MacroAssembler* masm) { 6596 void StoreArrayLiteralElementStub::Generate(MacroAssembler* masm) {
6598 // TODO(all): Possible optimisations in this function: 6597 // TODO(all): Possible optimisations in this function:
6599 // 1. Merge CheckFastElements and CheckFastSmiElements, so that the map 6598 // 1. Merge CheckFastElements and CheckFastSmiElements, so that the map
6600 // bitfield is loaded only once. 6599 // bitfield is loaded only once.
6601 // 2. Refactor the Ldr/Add sequence at the start of fast_elements and 6600 // 2. Refactor the Ldr/Add sequence at the start of fast_elements and
6602 // smi_element. 6601 // smi_element.
6603 6602
6604 // x0 value element value to store 6603 // x0 value element value to store
6605 // x1 array array literal 6604 // x3 index_smi element index as smi
6606 // x2 array_map map of array literal 6605 // sp[0] array_index_smi array literal index in function as smi
6607 // x3 index_smi element index as smi 6606 // sp[1] array array literal
6608 // x4 array_index_smi array literal index in function as smi
6609 6607
6610 Register value = x0; 6608 Register value = x0;
6609 Register index_smi = x3;
6610
6611 Register array = x1; 6611 Register array = x1;
6612 Register array_map = x2; 6612 Register array_map = x2;
6613 Register index_smi = x3;
6614 Register array_index_smi = x4; 6613 Register array_index_smi = x4;
6614 // TODO(jbramley): Implement PeekPair and use it here.
6615 __ Peek(array, 1 * kPointerSize);
6616 __ Peek(array_index_smi, 0 * kPointerSize);
6617 __ Ldr(array_map, FieldMemOperand(array, JSObject::kMapOffset));
6615 6618
6616 Label double_elements, smi_element, fast_elements, slow_elements; 6619 Label double_elements, smi_element, fast_elements, slow_elements;
6617 __ CheckFastElements(array_map, x10, &double_elements); 6620 __ CheckFastElements(array_map, x10, &double_elements);
6618 __ JumpIfSmi(value, &smi_element); 6621 __ JumpIfSmi(value, &smi_element);
6619 __ CheckFastSmiElements(array_map, x10, &fast_elements); 6622 __ CheckFastSmiElements(array_map, x10, &fast_elements);
6620 6623
6621 // Store into the array literal requires an elements transition. Call into 6624 // Store into the array literal requires an elements transition. Call into
6622 // the runtime. 6625 // the runtime.
6623 __ Bind(&slow_elements); 6626 __ Bind(&slow_elements);
6624 __ Push(array, index_smi, value); 6627 __ Push(array, index_smi, value);
(...skipping 531 matching lines...) Expand 10 before | Expand all | Expand 10 after
7156 // Initial map for the builtin Array function should be a map. 7159 // Initial map for the builtin Array function should be a map.
7157 __ Ldr(x10, FieldMemOperand(constructor, 7160 __ Ldr(x10, FieldMemOperand(constructor,
7158 JSFunction::kPrototypeOrInitialMapOffset)); 7161 JSFunction::kPrototypeOrInitialMapOffset));
7159 // Will both indicate a NULL and a Smi. 7162 // Will both indicate a NULL and a Smi.
7160 __ JumpIfSmi(x10, &unexpected_map); 7163 __ JumpIfSmi(x10, &unexpected_map);
7161 __ JumpIfObjectType(x10, x10, x11, MAP_TYPE, &map_ok); 7164 __ JumpIfObjectType(x10, x10, x11, MAP_TYPE, &map_ok);
7162 __ Bind(&unexpected_map); 7165 __ Bind(&unexpected_map);
7163 __ Abort("Unexpected initial map for Array function"); 7166 __ Abort("Unexpected initial map for Array function");
7164 __ Bind(&map_ok); 7167 __ Bind(&map_ok);
7165 7168
7166 // In type_info_cell, we expect either undefined or a valid 7169 // In type_info_cell, we expect either undefined or a valid Cell.
7167 // JSGlobalPropertyCell.
7168 Label okay_here; 7170 Label okay_here;
7169 Handle<Map> global_property_cell_map( 7171 Handle<Map> cell_map(masm->isolate()->heap()->global_property_cell_map());
7170 masm->isolate()->heap()->global_property_cell_map());
7171 __ CompareAndBranch(type_info_cell, Operand(undefined_sentinel), 7172 __ CompareAndBranch(type_info_cell, Operand(undefined_sentinel),
7172 eq, &okay_here); 7173 eq, &okay_here);
7173 __ Ldr(x10, FieldMemOperand(type_info_cell, 7174 __ Ldr(x10, FieldMemOperand(type_info_cell, Cell::kMapOffset));
7174 JSGlobalPropertyCell::kMapOffset)); 7175 __ Cmp(x10, Operand(cell_map));
7175 __ Cmp(x10, Operand(global_property_cell_map));
7176 __ Assert(eq, "Expected property cell in type_info_cell"); 7176 __ Assert(eq, "Expected property cell in type_info_cell");
7177 __ Bind(&okay_here); 7177 __ Bind(&okay_here);
7178 } 7178 }
7179 7179
7180 if (FLAG_optimize_constructed_arrays) { 7180 if (FLAG_optimize_constructed_arrays) {
7181 Register kind = x3; 7181 Register kind = x3;
7182 Label no_info, switch_ready; 7182 Label no_info, switch_ready;
7183 // Get the elements kind and case on that. 7183 // Get the elements kind and case on that.
7184 __ CompareAndBranch(type_info_cell, Operand(undefined_sentinel), 7184 __ CompareAndBranch(type_info_cell, Operand(undefined_sentinel),
7185 eq, &no_info); 7185 eq, &no_info);
7186 __ Ldr(kind, FieldMemOperand(type_info_cell, 7186 __ Ldr(kind, FieldMemOperand(type_info_cell, PropertyCell::kValueOffset));
7187 JSGlobalPropertyCell::kValueOffset));
7188 __ JumpIfNotSmi(kind, &no_info); 7187 __ JumpIfNotSmi(kind, &no_info);
7189 __ SmiUntag(kind); 7188 __ SmiUntag(kind);
7190 __ B(&switch_ready); 7189 __ B(&switch_ready);
7191 7190
7192 __ Bind(&no_info); 7191 __ Bind(&no_info);
7193 __ Mov(kind, GetInitialFastElementsKind()); 7192 __ Mov(kind, GetInitialFastElementsKind());
7194 __ Bind(&switch_ready); 7193 __ Bind(&switch_ready);
7195 7194
7196 if (argument_count_ == ANY) { 7195 if (argument_count_ == ANY) {
7197 Label zero_case, n_case; 7196 Label zero_case, n_case;
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after
7237 void InternalArrayConstructorStub::GenerateCase( 7236 void InternalArrayConstructorStub::GenerateCase(
7238 MacroAssembler* masm, ElementsKind kind) { 7237 MacroAssembler* masm, ElementsKind kind) {
7239 Label zero_case, n_case; 7238 Label zero_case, n_case;
7240 Register argc = x0; 7239 Register argc = x0;
7241 7240
7242 __ Cbz(argc, &zero_case); 7241 __ Cbz(argc, &zero_case);
7243 __ CompareAndBranch(argc, 1, ne, &n_case); 7242 __ CompareAndBranch(argc, 1, ne, &n_case);
7244 7243
7245 // One argument. 7244 // One argument.
7246 if (IsFastPackedElementsKind(kind)) { 7245 if (IsFastPackedElementsKind(kind)) {
7247 Label normal_sequence; 7246 Label packed_case;
7248 7247
7249 // We might need to create a holey array; look at the first argument. 7248 // We might need to create a holey array; look at the first argument.
7250 // TODO(jbramley): Is x3 significant? x10 is the convention in A64. 7249 __ Peek(x10, 0);
7251 __ Peek(x3, 0); 7250 __ Cbz(x10, &packed_case);
7252 __ Cbz(x3, &normal_sequence);
7253 7251
7254 InternalArraySingleArgumentConstructorStub 7252 InternalArraySingleArgumentConstructorStub
7255 stub1_holey(GetHoleyElementsKind(kind)); 7253 stub1_holey(GetHoleyElementsKind(kind));
7256 __ TailCallStub(&stub1_holey); 7254 __ TailCallStub(&stub1_holey);
7257 7255
7258 __ Bind(&normal_sequence); 7256 __ Bind(&packed_case);
7259 } 7257 }
7260 InternalArraySingleArgumentConstructorStub stub1(kind); 7258 InternalArraySingleArgumentConstructorStub stub1(kind);
7261 __ TailCallStub(&stub1); 7259 __ TailCallStub(&stub1);
7262 7260
7263 __ Bind(&zero_case); 7261 __ Bind(&zero_case);
7264 // No arguments. 7262 // No arguments.
7265 InternalArrayNoArgumentConstructorStub stub0(kind); 7263 InternalArrayNoArgumentConstructorStub stub0(kind);
7266 __ TailCallStub(&stub0); 7264 __ TailCallStub(&stub0);
7267 7265
7268 __ Bind(&n_case); 7266 __ Bind(&n_case);
(...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after
7340 __ Jump(generic_construct_stub, RelocInfo::CODE_TARGET); 7338 __ Jump(generic_construct_stub, RelocInfo::CODE_TARGET);
7341 } 7339 }
7342 } 7340 }
7343 7341
7344 7342
7345 #undef __ 7343 #undef __
7346 7344
7347 } } // namespace v8::internal 7345 } } // namespace v8::internal
7348 7346
7349 #endif // V8_TARGET_ARCH_A64 7347 #endif // V8_TARGET_ARCH_A64
OLDNEW
« no previous file with comments | « src/a64/assembler-a64-inl.h ('k') | src/a64/full-codegen-a64.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698