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

Side by Side Diff: runtime/vm/assembler_x64.cc

Issue 2112043002: Land Ivan's change of 'Remove support for verified memory handling' (Closed) Base URL: git@github.com:dart-lang/sdk.git@master
Patch Set: Address code review comments. Created 4 years, 5 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
« no previous file with comments | « runtime/vm/assembler_x64.h ('k') | runtime/vm/flow_graph_builder.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 (c) 2013, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file
2 // for details. All rights reserved. Use of this source code is governed by a 2 // for details. All rights reserved. Use of this source code is governed by a
3 // BSD-style license that can be found in the LICENSE file. 3 // BSD-style license that can be found in the LICENSE file.
4 4
5 #include "vm/globals.h" // NOLINT 5 #include "vm/globals.h" // NOLINT
6 #if defined(TARGET_ARCH_X64) 6 #if defined(TARGET_ARCH_X64)
7 7
8 #include "vm/assembler.h" 8 #include "vm/assembler.h"
9 #include "vm/cpu.h" 9 #include "vm/cpu.h"
10 #include "vm/heap.h" 10 #include "vm/heap.h"
(...skipping 2471 matching lines...) Expand 10 before | Expand all | Expand 10 after
2482 2482
2483 2483
2484 void Assembler::hlt() { 2484 void Assembler::hlt() {
2485 AssemblerBuffer::EnsureCapacity ensured(&buffer_); 2485 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
2486 EmitUint8(0xF4); 2486 EmitUint8(0xF4);
2487 } 2487 }
2488 2488
2489 2489
2490 void Assembler::j(Condition condition, Label* label, bool near) { 2490 void Assembler::j(Condition condition, Label* label, bool near) {
2491 AssemblerBuffer::EnsureCapacity ensured(&buffer_); 2491 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
2492 if (VerifiedMemory::enabled()) {
2493 near = Assembler::kFarJump;
2494 }
2495 if (label->IsBound()) { 2492 if (label->IsBound()) {
2496 static const int kShortSize = 2; 2493 static const int kShortSize = 2;
2497 static const int kLongSize = 6; 2494 static const int kLongSize = 6;
2498 intptr_t offset = label->Position() - buffer_.Size(); 2495 intptr_t offset = label->Position() - buffer_.Size();
2499 ASSERT(offset <= 0); 2496 ASSERT(offset <= 0);
2500 if (Utils::IsInt(8, offset - kShortSize)) { 2497 if (Utils::IsInt(8, offset - kShortSize)) {
2501 EmitUint8(0x70 + condition); 2498 EmitUint8(0x70 + condition);
2502 EmitUint8((offset - kShortSize) & 0xFF); 2499 EmitUint8((offset - kShortSize) & 0xFF);
2503 } else { 2500 } else {
2504 EmitUint8(0x0F); 2501 EmitUint8(0x0F);
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after
2539 void Assembler::jmp(const Address& dst) { 2536 void Assembler::jmp(const Address& dst) {
2540 AssemblerBuffer::EnsureCapacity ensured(&buffer_); 2537 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
2541 EmitOperandREX(4, dst, REX_NONE); 2538 EmitOperandREX(4, dst, REX_NONE);
2542 EmitUint8(0xFF); 2539 EmitUint8(0xFF);
2543 EmitOperand(4, dst); 2540 EmitOperand(4, dst);
2544 } 2541 }
2545 2542
2546 2543
2547 void Assembler::jmp(Label* label, bool near) { 2544 void Assembler::jmp(Label* label, bool near) {
2548 AssemblerBuffer::EnsureCapacity ensured(&buffer_); 2545 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
2549 if (VerifiedMemory::enabled()) {
2550 near = Assembler::kFarJump;
2551 }
2552 if (label->IsBound()) { 2546 if (label->IsBound()) {
2553 static const int kShortSize = 2; 2547 static const int kShortSize = 2;
2554 static const int kLongSize = 5; 2548 static const int kLongSize = 5;
2555 intptr_t offset = label->Position() - buffer_.Size(); 2549 intptr_t offset = label->Position() - buffer_.Size();
2556 ASSERT(offset <= 0); 2550 ASSERT(offset <= 0);
2557 if (Utils::IsInt(8, offset - kShortSize)) { 2551 if (Utils::IsInt(8, offset - kShortSize)) {
2558 EmitUint8(0xEB); 2552 EmitUint8(0xEB);
2559 EmitUint8((offset - kShortSize) & 0xFF); 2553 EmitUint8((offset - kShortSize) & 0xFF);
2560 } else { 2554 } else {
2561 EmitUint8(0xE9); 2555 EmitUint8(0xE9);
(...skipping 375 matching lines...) Expand 10 before | Expand all | Expand 10 after
2937 // Mask out higher, uninteresting bits which were polluted by dest. 2931 // Mask out higher, uninteresting bits which were polluted by dest.
2938 andl(value, Immediate(kObjectAlignment - 1)); 2932 andl(value, Immediate(kObjectAlignment - 1));
2939 // Compare with the expected bit pattern. 2933 // Compare with the expected bit pattern.
2940 cmpl(value, Immediate( 2934 cmpl(value, Immediate(
2941 (kNewObjectAlignmentOffset >> 1) + kHeapObjectTag + 2935 (kNewObjectAlignmentOffset >> 1) + kHeapObjectTag +
2942 kOldObjectAlignmentOffset + kHeapObjectTag)); 2936 kOldObjectAlignmentOffset + kHeapObjectTag));
2943 j(NOT_ZERO, no_update, Assembler::kNearJump); 2937 j(NOT_ZERO, no_update, Assembler::kNearJump);
2944 } 2938 }
2945 2939
2946 2940
2947 void Assembler::VerifyHeapWord(const Address& address,
2948 FieldContent old_content) {
2949 #if defined(DEBUG)
2950 switch (old_content) {
2951 case kEmptyOrSmiOrNull:
2952 VerifyUninitialized(address);
2953 break;
2954 case kHeapObjectOrSmi:
2955 VerifyObjectOrSmi(address);
2956 break;
2957 case kOnlySmi:
2958 VerifySmi(address);
2959 break;
2960 }
2961 #endif // DEBUG
2962 if (VerifiedMemory::enabled()) {
2963 Register addr_reg = RDX;
2964 Register value = RBX;
2965 // Preserve registers.
2966 pushq(addr_reg);
2967 pushq(value);
2968 leaq(addr_reg, address);
2969 // ASSERT(*address == *(address + offset))
2970 movq(value, Address(addr_reg, 0));
2971 cmpq(value, Address(addr_reg, VerifiedMemory::offset()));
2972 Label ok;
2973 j(EQUAL, &ok);
2974 static const bool kFixedLengthEncoding = true;
2975 Stop("Write barrier verification failed", kFixedLengthEncoding);
2976 Bind(&ok);
2977 popq(value);
2978 popq(addr_reg);
2979 }
2980 }
2981
2982
2983 void Assembler::VerifiedWrite(const Address& dest,
2984 Register value,
2985 FieldContent old_content) {
2986 VerifyHeapWord(dest, old_content);
2987 movq(dest, value);
2988 if (VerifiedMemory::enabled()) {
2989 Register temp = (value == RDX) ? RCX : RDX;
2990 pushq(temp);
2991 leaq(temp, dest);
2992 movq(Address(temp, VerifiedMemory::offset()), value);
2993 popq(temp);
2994 }
2995 }
2996
2997
2998 #if defined(DEBUG)
2999 void Assembler::VerifyObjectOrSmi(const Address& dest) {
3000 Label ok;
3001 testb(dest, Immediate(kHeapObjectTag));
3002 j(ZERO, &ok, Assembler::kNearJump);
3003 // Non-smi case: Verify object pointer is word-aligned when untagged.
3004 COMPILE_ASSERT(kHeapObjectTag == 1);
3005 testb(dest, Immediate((kWordSize - 1) - kHeapObjectTag));
3006 j(ZERO, &ok, Assembler::kNearJump);
3007 static const bool kFixedLengthEncoding = true;
3008 Stop("Expected heap object or Smi", kFixedLengthEncoding);
3009 Bind(&ok);
3010 }
3011
3012
3013 void Assembler::VerifyUninitialized(const Address& dest) {
3014 Label ok;
3015 testb(dest, Immediate(kHeapObjectTag));
3016 j(ZERO, &ok, Assembler::kNearJump);
3017 // Non-smi case: Check for the special zap word or null.
3018 #if defined(DEBUG)
3019 cmpq(dest, Immediate(Heap::kZap64Bits));
3020 j(EQUAL, &ok, Assembler::kNearJump);
3021 #else
3022 #error Only supported in DEBUG mode
3023 #endif
3024 LoadObject(TMP, Object::null_object());
3025 cmpq(dest, TMP);
3026 j(EQUAL, &ok, Assembler::kNearJump);
3027 static const bool kFixedLengthEncoding = true;
3028 Stop("Expected zapped, Smi or null", kFixedLengthEncoding);
3029 Bind(&ok);
3030 }
3031
3032
3033 void Assembler::VerifySmi(const Address& dest, const char* stop_msg) {
3034 Label done;
3035 testb(dest, Immediate(kHeapObjectTag));
3036 j(ZERO, &done, Assembler::kNearJump);
3037 static const bool kFixedLengthEncoding = true;
3038 Stop(stop_msg, kFixedLengthEncoding);
3039 Bind(&done);
3040 }
3041 #endif // defined(DEBUG)
3042
3043
3044 void Assembler::StoreIntoObject(Register object, 2941 void Assembler::StoreIntoObject(Register object,
3045 const Address& dest, 2942 const Address& dest,
3046 Register value, 2943 Register value,
3047 bool can_value_be_smi) { 2944 bool can_value_be_smi) {
3048 ASSERT(object != value); 2945 ASSERT(object != value);
3049 VerifiedWrite(dest, value, kHeapObjectOrSmi); 2946 movq(dest, value);
3050 Label done; 2947 Label done;
3051 if (can_value_be_smi) { 2948 if (can_value_be_smi) {
3052 StoreIntoObjectFilter(object, value, &done); 2949 StoreIntoObjectFilter(object, value, &done);
3053 } else { 2950 } else {
3054 StoreIntoObjectFilterNoSmi(object, value, &done); 2951 StoreIntoObjectFilterNoSmi(object, value, &done);
3055 } 2952 }
3056 // A store buffer update is required. 2953 // A store buffer update is required.
3057 if (value != RDX) pushq(RDX); 2954 if (value != RDX) pushq(RDX);
3058 if (object != RDX) { 2955 if (object != RDX) {
3059 movq(RDX, object); 2956 movq(RDX, object);
3060 } 2957 }
3061 pushq(CODE_REG); 2958 pushq(CODE_REG);
3062 movq(CODE_REG, Address(THR, Thread::update_store_buffer_code_offset())); 2959 movq(CODE_REG, Address(THR, Thread::update_store_buffer_code_offset()));
3063 movq(TMP, Address(THR, Thread::update_store_buffer_entry_point_offset())); 2960 movq(TMP, Address(THR, Thread::update_store_buffer_entry_point_offset()));
3064 call(TMP); 2961 call(TMP);
3065 2962
3066 popq(CODE_REG); 2963 popq(CODE_REG);
3067 if (value != RDX) popq(RDX); 2964 if (value != RDX) popq(RDX);
3068 Bind(&done); 2965 Bind(&done);
3069 } 2966 }
3070 2967
3071 2968
3072 void Assembler::StoreIntoObjectNoBarrier(Register object, 2969 void Assembler::StoreIntoObjectNoBarrier(Register object,
3073 const Address& dest, 2970 const Address& dest,
3074 Register value, 2971 Register value) {
3075 FieldContent old_content) { 2972 movq(dest, value);
3076 VerifiedWrite(dest, value, old_content);
3077 #if defined(DEBUG) 2973 #if defined(DEBUG)
3078 Label done; 2974 Label done;
3079 pushq(value); 2975 pushq(value);
3080 StoreIntoObjectFilter(object, value, &done); 2976 StoreIntoObjectFilter(object, value, &done);
3081 Stop("Store buffer update is required"); 2977 Stop("Store buffer update is required");
3082 Bind(&done); 2978 Bind(&done);
3083 popq(value); 2979 popq(value);
3084 #endif // defined(DEBUG) 2980 #endif // defined(DEBUG)
3085 // No store buffer update. 2981 // No store buffer update.
3086 } 2982 }
3087 2983
3088 2984
3089 void Assembler::StoreIntoObjectNoBarrier(Register object, 2985 void Assembler::StoreIntoObjectNoBarrier(Register object,
3090 const Address& dest, 2986 const Address& dest,
3091 const Object& value, 2987 const Object& value) {
3092 FieldContent old_content) {
3093 ASSERT(!value.IsICData() || ICData::Cast(value).IsOriginal()); 2988 ASSERT(!value.IsICData() || ICData::Cast(value).IsOriginal());
3094 ASSERT(!value.IsField() || Field::Cast(value).IsOriginal()); 2989 ASSERT(!value.IsField() || Field::Cast(value).IsOriginal());
3095 VerifyHeapWord(dest, old_content); 2990 StoreObject(dest, value);
3096 if (VerifiedMemory::enabled()) {
3097 const Register temp = RCX;
3098 pushq(temp);
3099 leaq(temp, dest);
3100 StoreObject(Address(temp, 0), value);
3101 StoreObject(Address(temp, VerifiedMemory::offset()), value);
3102 popq(temp);
3103 } else {
3104 StoreObject(dest, value);
3105 }
3106 // TODO(koda): Use 'object', verify that generational barrier's not needed.
3107 } 2991 }
3108 2992
3109 2993
3110 void Assembler::StoreIntoSmiField(const Address& dest, Register value) { 2994 void Assembler::StoreIntoSmiField(const Address& dest, Register value) {
3111 #if defined(DEBUG) 2995 #if defined(DEBUG)
3112 Label done; 2996 Label done;
3113 testq(value, Immediate(kHeapObjectTag)); 2997 testq(value, Immediate(kHeapObjectTag));
3114 j(ZERO, &done); 2998 j(ZERO, &done);
3115 Stop("New value must be Smi."); 2999 Stop("New value must be Smi.");
3116 Bind(&done); 3000 Bind(&done);
3117 #endif // defined(DEBUG) 3001 #endif // defined(DEBUG)
3118 VerifiedWrite(dest, value, kOnlySmi); 3002 movq(dest, value);
3119 } 3003 }
3120 3004
3121 3005
3122 void Assembler::ZeroInitSmiField(const Address& dest) { 3006 void Assembler::ZeroInitSmiField(const Address& dest) {
3123 // TODO(koda): Add VerifySmi once we distinguish initalization.
3124 VerifyHeapWord(dest, kEmptyOrSmiOrNull);
3125 Immediate zero(Smi::RawValue(0)); 3007 Immediate zero(Smi::RawValue(0));
3126 movq(dest, zero); 3008 movq(dest, zero);
3127 if (VerifiedMemory::enabled()) {
3128 Register temp = RCX;
3129 pushq(temp);
3130 leaq(temp, dest);
3131 movq(Address(temp, VerifiedMemory::offset()), zero);
3132 popq(temp);
3133 }
3134 } 3009 }
3135 3010
3136 3011
3137 void Assembler::IncrementSmiField(const Address& dest, int64_t increment) { 3012 void Assembler::IncrementSmiField(const Address& dest, int64_t increment) {
3138 // Note: FlowGraphCompiler::EdgeCounterIncrementSizeInBytes depends on 3013 // Note: FlowGraphCompiler::EdgeCounterIncrementSizeInBytes depends on
3139 // the length of this instruction sequence. 3014 // the length of this instruction sequence.
3140 // TODO(koda): Add VerifySmi once we distinguish initalization.
3141 VerifyHeapWord(dest, kOnlySmi);
3142 Immediate inc_imm(Smi::RawValue(increment)); 3015 Immediate inc_imm(Smi::RawValue(increment));
3143 addq(dest, inc_imm); 3016 addq(dest, inc_imm);
3144 if (VerifiedMemory::enabled()) {
3145 Register temp = RCX;
3146 pushq(temp);
3147 leaq(temp, dest);
3148 addq(Address(temp, VerifiedMemory::offset()), inc_imm);
3149 popq(temp);
3150 }
3151 } 3017 }
3152 3018
3153 3019
3154 void Assembler::DoubleNegate(XmmRegister d) { 3020 void Assembler::DoubleNegate(XmmRegister d) {
3155 // {0x8000000000000000LL, 0x8000000000000000LL} 3021 // {0x8000000000000000LL, 0x8000000000000000LL}
3156 movq(TMP, Address(THR, Thread::double_negate_address_offset())); 3022 movq(TMP, Address(THR, Thread::double_negate_address_offset()));
3157 xorpd(d, Address(TMP, 0)); 3023 xorpd(d, Address(TMP, 0));
3158 } 3024 }
3159 3025
3160 3026
(...skipping 757 matching lines...) Expand 10 before | Expand all | Expand 10 after
3918 3784
3919 3785
3920 const char* Assembler::FpuRegisterName(FpuRegister reg) { 3786 const char* Assembler::FpuRegisterName(FpuRegister reg) {
3921 ASSERT((0 <= reg) && (reg < kNumberOfXmmRegisters)); 3787 ASSERT((0 <= reg) && (reg < kNumberOfXmmRegisters));
3922 return xmm_reg_names[reg]; 3788 return xmm_reg_names[reg];
3923 } 3789 }
3924 3790
3925 } // namespace dart 3791 } // namespace dart
3926 3792
3927 #endif // defined TARGET_ARCH_X64 3793 #endif // defined TARGET_ARCH_X64
OLDNEW
« no previous file with comments | « runtime/vm/assembler_x64.h ('k') | runtime/vm/flow_graph_builder.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698