| 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 1628 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1639 ? ObjectLiteral::kFastElements | 1639 ? ObjectLiteral::kFastElements |
| 1640 : ObjectLiteral::kNoFlags; | 1640 : ObjectLiteral::kNoFlags; |
| 1641 flags |= expr->has_function() | 1641 flags |= expr->has_function() |
| 1642 ? ObjectLiteral::kHasFunction | 1642 ? ObjectLiteral::kHasFunction |
| 1643 : ObjectLiteral::kNoFlags; | 1643 : ObjectLiteral::kNoFlags; |
| 1644 __ Mov(x0, Operand(Smi::FromInt(flags))); | 1644 __ Mov(x0, Operand(Smi::FromInt(flags))); |
| 1645 int properties_count = constant_properties->length() / 2; | 1645 int properties_count = constant_properties->length() / 2; |
| 1646 const int max_cloned_properties = | 1646 const int max_cloned_properties = |
| 1647 FastCloneShallowObjectStub::kMaximumClonedProperties; | 1647 FastCloneShallowObjectStub::kMaximumClonedProperties; |
| 1648 if ((FLAG_track_double_fields && expr->may_store_doubles()) || | 1648 if ((FLAG_track_double_fields && expr->may_store_doubles()) || |
| 1649 expr->depth() > 1) { | 1649 (expr->depth() > 1 || Serializer::enabled()) || |
| 1650 (flags != ObjectLiteral::kFastElements) || |
| 1651 (properties_count > max_cloned_properties)) { |
| 1650 __ Push(x3, x2, x1, x0); | 1652 __ Push(x3, x2, x1, x0); |
| 1651 __ CallRuntime(Runtime::kCreateObjectLiteral, 4); | 1653 __ CallRuntime(Runtime::kCreateObjectLiteral, 4); |
| 1652 } else if (Serializer::enabled() || (flags != ObjectLiteral::kFastElements) || | |
| 1653 (properties_count > max_cloned_properties)) { | |
| 1654 __ Push(x3, x2, x1, x0); | |
| 1655 __ CallRuntime(Runtime::kCreateObjectLiteralShallow, 4); | |
| 1656 } else { | 1654 } else { |
| 1657 FastCloneShallowObjectStub stub(properties_count); | 1655 FastCloneShallowObjectStub stub(properties_count); |
| 1658 __ CallStub(&stub); | 1656 __ CallStub(&stub); |
| 1659 } | 1657 } |
| 1660 | 1658 |
| 1661 // If result_saved is true the result is on top of the stack. If | 1659 // If result_saved is true the result is on top of the stack. If |
| 1662 // result_saved is false the result is in x0. | 1660 // result_saved is false the result is in x0. |
| 1663 bool result_saved = false; | 1661 bool result_saved = false; |
| 1664 | 1662 |
| 1665 // Mark all computed expressions that are bound to a key that | 1663 // Mark all computed expressions that are bound to a key that |
| (...skipping 3271 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4937 // Uncook the return address (see EnterFinallyBlock). | 4935 // Uncook the return address (see EnterFinallyBlock). |
| 4938 __ SmiUntag(x10); | 4936 __ SmiUntag(x10); |
| 4939 __ Add(x11, x10, Operand(masm_->CodeObject())); | 4937 __ Add(x11, x10, Operand(masm_->CodeObject())); |
| 4940 __ Br(x11); | 4938 __ Br(x11); |
| 4941 } | 4939 } |
| 4942 | 4940 |
| 4943 | 4941 |
| 4944 #undef __ | 4942 #undef __ |
| 4945 | 4943 |
| 4946 | 4944 |
| 4945 // The back edge bookkeeping code matches the pattern: |
| 4946 // |
| 4947 // <decrement profiling counter> |
| 4948 // .. .. .. .. b.pl ok |
| 4949 // .. .. .. .. ldr x16, pc+<interrupt stub address> |
| 4950 // .. .. .. .. blr x16 |
| 4951 // ok-label |
| 4952 // |
| 4953 // We patch the code to the following form: |
| 4954 // |
| 4955 // <decrement profiling counter> |
| 4956 // .. .. .. .. mov x0, x0 (NOP) |
| 4957 // .. .. .. .. ldr x16, pc+<on-stack replacement address> |
| 4958 // .. .. .. .. blr x16 |
| 4959 void BackEdgeTable::PatchAt(Code* unoptimized_code, |
| 4960 Address pc_after, |
| 4961 Code* replacement_code) { |
| 4962 // Turn the jump into a nop. |
| 4963 Instruction* jump = Instruction::Cast(pc_after)->preceding(3); |
| 4964 PatchingAssembler patcher(jump, 1); |
| 4965 patcher.nop(Assembler::INTERRUPT_CODE_NOP); |
| 4966 |
| 4967 // Replace the call address. |
| 4968 Instruction* load = Instruction::Cast(pc_after)->preceding(2); |
| 4969 Address interrupt_address_pointer = |
| 4970 reinterpret_cast<Address>(load) + load->ImmPCOffset(); |
| 4971 Memory::uint64_at(interrupt_address_pointer) = |
| 4972 reinterpret_cast<uint64_t>(replacement_code->entry()); |
| 4973 |
| 4974 unoptimized_code->GetHeap()->incremental_marking()->RecordCodeTargetPatch( |
| 4975 unoptimized_code, pc_after - 2 * kInstructionSize, replacement_code); |
| 4976 } |
| 4977 |
| 4978 |
| 4979 void BackEdgeTable::RevertAt(Code* unoptimized_code, |
| 4980 Address pc_after, |
| 4981 Code* interrupt_code) { |
| 4982 // Turn the nop into a jump. |
| 4983 Instruction* jump = Instruction::Cast(pc_after)->preceding(3); |
| 4984 PatchingAssembler patcher(jump, 1); |
| 4985 patcher.b(6, pl); // The ok label is 6 instructions later. |
| 4986 |
| 4987 // Replace the call address. |
| 4988 Instruction* load = Instruction::Cast(pc_after)->preceding(2); |
| 4989 Address interrupt_address_pointer = |
| 4990 reinterpret_cast<Address>(load) + load->ImmPCOffset(); |
| 4991 Memory::uint64_at(interrupt_address_pointer) = |
| 4992 reinterpret_cast<uint64_t>(interrupt_code->entry()); |
| 4993 |
| 4994 interrupt_code->GetHeap()->incremental_marking()->RecordCodeTargetPatch( |
| 4995 unoptimized_code, pc_after - 2 * kInstructionSize, interrupt_code); |
| 4996 } |
| 4997 |
| 4998 |
| 4999 #ifdef DEBUG |
| 5000 BackEdgeTable::BackEdgeState BackEdgeTable::GetBackEdgeState( |
| 5001 Isolate* isolate, |
| 5002 Code* unoptimized_code, |
| 5003 Address pc_after) { |
| 5004 // TODO(jbramley): There should be some extra assertions here (as in the ARM |
| 5005 // back-end), but this function is gone in bleeding_edge so it might not |
| 5006 // matter anyway. |
| 5007 Instruction* jump_or_nop = Instruction::Cast(pc_after)->preceding(3); |
| 5008 return jump_or_nop->IsNop(Assembler::INTERRUPT_CODE_NOP) ? |
| 5009 ON_STACK_REPLACEMENT : INTERRUPT; |
| 5010 } |
| 5011 #endif |
| 5012 |
| 5013 |
| 4947 #define __ ACCESS_MASM(masm()) | 5014 #define __ ACCESS_MASM(masm()) |
| 4948 | 5015 |
| 4949 | 5016 |
| 4950 FullCodeGenerator::NestedStatement* FullCodeGenerator::TryFinally::Exit( | 5017 FullCodeGenerator::NestedStatement* FullCodeGenerator::TryFinally::Exit( |
| 4951 int* stack_depth, | 5018 int* stack_depth, |
| 4952 int* context_length) { | 5019 int* context_length) { |
| 4953 ASM_LOCATION("FullCodeGenerator::TryFinally::Exit"); | 5020 ASM_LOCATION("FullCodeGenerator::TryFinally::Exit"); |
| 4954 // The macros used here must preserve the result register. | 5021 // The macros used here must preserve the result register. |
| 4955 | 5022 |
| 4956 // Because the handler block contains the context of the finally | 5023 // Because the handler block contains the context of the finally |
| (...skipping 14 matching lines...) Expand all Loading... |
| 4971 return previous_; | 5038 return previous_; |
| 4972 } | 5039 } |
| 4973 | 5040 |
| 4974 | 5041 |
| 4975 #undef __ | 5042 #undef __ |
| 4976 | 5043 |
| 4977 | 5044 |
| 4978 } } // namespace v8::internal | 5045 } } // namespace v8::internal |
| 4979 | 5046 |
| 4980 #endif // V8_TARGET_ARCH_A64 | 5047 #endif // V8_TARGET_ARCH_A64 |
| OLD | NEW |