OLD | NEW |
1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 the V8 project authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "src/code-stubs.h" | 5 #include "src/code-stubs.h" |
6 | 6 |
7 #include <sstream> | 7 #include <sstream> |
8 | 8 |
9 #include "src/ast/ast.h" | 9 #include "src/ast/ast.h" |
10 #include "src/bootstrapper.h" | 10 #include "src/bootstrapper.h" |
(...skipping 4453 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4464 if (!representation.IsTagged()) { | 4464 if (!representation.IsTagged()) { |
4465 assembler->Bind(&miss); | 4465 assembler->Bind(&miss); |
4466 { | 4466 { |
4467 assembler->Comment("Miss"); | 4467 assembler->Comment("Miss"); |
4468 assembler->TailCallRuntime(Runtime::kStoreIC_Miss, context, receiver, | 4468 assembler->TailCallRuntime(Runtime::kStoreIC_Miss, context, receiver, |
4469 name, value, slot, vector); | 4469 name, value, slot, vector); |
4470 } | 4470 } |
4471 } | 4471 } |
4472 } | 4472 } |
4473 | 4473 |
| 4474 void StoreGlobalStub::GenerateAssembly(CodeStubAssembler* assembler) const { |
| 4475 typedef CodeStubAssembler::Label Label; |
| 4476 typedef compiler::Node Node; |
| 4477 |
| 4478 assembler->Comment( |
| 4479 "StoreGlobalStub: cell_type=%d, constant_type=%d, check_global=%d", |
| 4480 cell_type(), PropertyCellType::kConstantType == cell_type() |
| 4481 ? static_cast<int>(constant_type()) |
| 4482 : -1, |
| 4483 check_global()); |
| 4484 |
| 4485 Node* receiver = assembler->Parameter(Descriptor::kReceiver); |
| 4486 Node* name = assembler->Parameter(Descriptor::kName); |
| 4487 Node* value = assembler->Parameter(Descriptor::kValue); |
| 4488 Node* slot = assembler->Parameter(Descriptor::kSlot); |
| 4489 Node* vector = assembler->Parameter(Descriptor::kVector); |
| 4490 Node* context = assembler->Parameter(Descriptor::kContext); |
| 4491 |
| 4492 Label miss(assembler); |
| 4493 |
| 4494 if (check_global()) { |
| 4495 // Check that the map of the global has not changed: use a placeholder map |
| 4496 // that will be replaced later with the global object's map. |
| 4497 Node* proxy_map = assembler->LoadMap(receiver); |
| 4498 Node* global = assembler->LoadObjectField(proxy_map, Map::kPrototypeOffset); |
| 4499 Node* map_cell = assembler->HeapConstant(isolate()->factory()->NewWeakCell( |
| 4500 StoreGlobalStub::global_map_placeholder(isolate()))); |
| 4501 Node* expected_map = assembler->LoadWeakCellValue(map_cell); |
| 4502 Node* map = assembler->LoadMap(global); |
| 4503 assembler->GotoIf(assembler->WordNotEqual(expected_map, map), &miss); |
| 4504 } |
| 4505 |
| 4506 Node* weak_cell = assembler->HeapConstant(isolate()->factory()->NewWeakCell( |
| 4507 StoreGlobalStub::property_cell_placeholder(isolate()))); |
| 4508 Node* cell = assembler->LoadWeakCellValue(weak_cell); |
| 4509 assembler->GotoIf(assembler->WordIsSmi(cell), &miss); |
| 4510 |
| 4511 // Load the payload of the global parameter cell. A hole indicates that the |
| 4512 // cell has been invalidated and that the store must be handled by the |
| 4513 // runtime. |
| 4514 Node* cell_contents = |
| 4515 assembler->LoadObjectField(cell, PropertyCell::kValueOffset); |
| 4516 |
| 4517 PropertyCellType cell_type = this->cell_type(); |
| 4518 if (cell_type == PropertyCellType::kConstant || |
| 4519 cell_type == PropertyCellType::kUndefined) { |
| 4520 // This is always valid for all states a cell can be in. |
| 4521 assembler->GotoIf(assembler->WordNotEqual(cell_contents, value), &miss); |
| 4522 } else { |
| 4523 assembler->GotoIf( |
| 4524 assembler->WordEqual(cell_contents, assembler->TheHoleConstant()), |
| 4525 &miss); |
| 4526 |
| 4527 // When dealing with constant types, the type may be allowed to change, as |
| 4528 // long as optimized code remains valid. |
| 4529 bool value_is_smi = false; |
| 4530 if (cell_type == PropertyCellType::kConstantType) { |
| 4531 switch (constant_type()) { |
| 4532 case PropertyCellConstantType::kSmi: |
| 4533 assembler->GotoUnless(assembler->WordIsSmi(value), &miss); |
| 4534 value_is_smi = true; |
| 4535 break; |
| 4536 case PropertyCellConstantType::kStableMap: { |
| 4537 // It is sufficient here to check that the value and cell contents |
| 4538 // have identical maps, no matter if they are stable or not or if they |
| 4539 // are the maps that were originally in the cell or not. If optimized |
| 4540 // code will deopt when a cell has a unstable map and if it has a |
| 4541 // dependency on a stable map, it will deopt if the map destabilizes. |
| 4542 assembler->GotoIf(assembler->WordIsSmi(value), &miss); |
| 4543 assembler->GotoIf(assembler->WordIsSmi(cell_contents), &miss); |
| 4544 Node* expected_map = assembler->LoadMap(cell_contents); |
| 4545 Node* map = assembler->LoadMap(value); |
| 4546 assembler->GotoIf(assembler->WordNotEqual(expected_map, map), &miss); |
| 4547 break; |
| 4548 } |
| 4549 } |
| 4550 } |
| 4551 if (value_is_smi) { |
| 4552 assembler->StoreObjectFieldNoWriteBarrier( |
| 4553 cell, PropertyCell::kValueOffset, value); |
| 4554 } else { |
| 4555 assembler->StoreObjectField(cell, PropertyCell::kValueOffset, value); |
| 4556 } |
| 4557 } |
| 4558 |
| 4559 assembler->Return(value); |
| 4560 |
| 4561 assembler->Bind(&miss); |
| 4562 { |
| 4563 assembler->Comment("Miss"); |
| 4564 assembler->TailCallRuntime(Runtime::kStoreIC_Miss, context, receiver, name, |
| 4565 value, slot, vector); |
| 4566 } |
| 4567 } |
| 4568 |
4474 // static | 4569 // static |
4475 compiler::Node* LessThanStub::Generate(CodeStubAssembler* assembler, | 4570 compiler::Node* LessThanStub::Generate(CodeStubAssembler* assembler, |
4476 compiler::Node* lhs, compiler::Node* rhs, | 4571 compiler::Node* lhs, compiler::Node* rhs, |
4477 compiler::Node* context) { | 4572 compiler::Node* context) { |
4478 return GenerateAbstractRelationalComparison(assembler, kLessThan, lhs, rhs, | 4573 return GenerateAbstractRelationalComparison(assembler, kLessThan, lhs, rhs, |
4479 context); | 4574 context); |
4480 } | 4575 } |
4481 | 4576 |
4482 // static | 4577 // static |
4483 compiler::Node* LessThanOrEqualStub::Generate(CodeStubAssembler* assembler, | 4578 compiler::Node* LessThanOrEqualStub::Generate(CodeStubAssembler* assembler, |
(...skipping 1402 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5886 | 5981 |
5887 if (type == MachineType::Pointer()) { | 5982 if (type == MachineType::Pointer()) { |
5888 return Representation::External(); | 5983 return Representation::External(); |
5889 } | 5984 } |
5890 | 5985 |
5891 return Representation::Tagged(); | 5986 return Representation::Tagged(); |
5892 } | 5987 } |
5893 | 5988 |
5894 } // namespace internal | 5989 } // namespace internal |
5895 } // namespace v8 | 5990 } // namespace v8 |
OLD | NEW |