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

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

Issue 727623002: Support verified heap pointer writes on x64. (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: Created 6 years, 1 month 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 | « runtime/vm/assembler_x64.h ('k') | runtime/vm/code_patcher_x64.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" 5 #include "vm/globals.h"
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 2366 matching lines...) Expand 10 before | Expand all | Expand 10 after
2377 2377
2378 2378
2379 void Assembler::hlt() { 2379 void Assembler::hlt() {
2380 AssemblerBuffer::EnsureCapacity ensured(&buffer_); 2380 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
2381 EmitUint8(0xF4); 2381 EmitUint8(0xF4);
2382 } 2382 }
2383 2383
2384 2384
2385 void Assembler::j(Condition condition, Label* label, bool near) { 2385 void Assembler::j(Condition condition, Label* label, bool near) {
2386 AssemblerBuffer::EnsureCapacity ensured(&buffer_); 2386 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
2387 if (VerifiedMemory::enabled()) {
2388 near = Assembler::kFarJump;
2389 }
2387 if (label->IsBound()) { 2390 if (label->IsBound()) {
2388 static const int kShortSize = 2; 2391 static const int kShortSize = 2;
2389 static const int kLongSize = 6; 2392 static const int kLongSize = 6;
2390 intptr_t offset = label->Position() - buffer_.Size(); 2393 intptr_t offset = label->Position() - buffer_.Size();
2391 ASSERT(offset <= 0); 2394 ASSERT(offset <= 0);
2392 if (Utils::IsInt(8, offset - kShortSize)) { 2395 if (Utils::IsInt(8, offset - kShortSize)) {
2393 EmitUint8(0x70 + condition); 2396 EmitUint8(0x70 + condition);
2394 EmitUint8((offset - kShortSize) & 0xFF); 2397 EmitUint8((offset - kShortSize) & 0xFF);
2395 } else { 2398 } else {
2396 EmitUint8(0x0F); 2399 EmitUint8(0x0F);
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after
2429 AssemblerBuffer::EnsureCapacity ensured(&buffer_); 2432 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
2430 Operand operand(reg); 2433 Operand operand(reg);
2431 EmitOperandREX(4, operand, REX_NONE); 2434 EmitOperandREX(4, operand, REX_NONE);
2432 EmitUint8(0xFF); 2435 EmitUint8(0xFF);
2433 EmitOperand(4, operand); 2436 EmitOperand(4, operand);
2434 } 2437 }
2435 2438
2436 2439
2437 void Assembler::jmp(Label* label, bool near) { 2440 void Assembler::jmp(Label* label, bool near) {
2438 AssemblerBuffer::EnsureCapacity ensured(&buffer_); 2441 AssemblerBuffer::EnsureCapacity ensured(&buffer_);
2442 if (VerifiedMemory::enabled()) {
2443 near = Assembler::kFarJump;
2444 }
2439 if (label->IsBound()) { 2445 if (label->IsBound()) {
2440 static const int kShortSize = 2; 2446 static const int kShortSize = 2;
2441 static const int kLongSize = 5; 2447 static const int kLongSize = 5;
2442 intptr_t offset = label->Position() - buffer_.Size(); 2448 intptr_t offset = label->Position() - buffer_.Size();
2443 ASSERT(offset <= 0); 2449 ASSERT(offset <= 0);
2444 if (Utils::IsInt(8, offset - kShortSize)) { 2450 if (Utils::IsInt(8, offset - kShortSize)) {
2445 EmitUint8(0xEB); 2451 EmitUint8(0xEB);
2446 EmitUint8((offset - kShortSize) & 0xFF); 2452 EmitUint8((offset - kShortSize) & 0xFF);
2447 } else { 2453 } else {
2448 EmitUint8(0xE9); 2454 EmitUint8(0xE9);
(...skipping 415 matching lines...) Expand 10 before | Expand all | Expand 10 after
2864 // Mask out higher, uninteresting bits which were polluted by dest. 2870 // Mask out higher, uninteresting bits which were polluted by dest.
2865 andl(value, Immediate(kObjectAlignment - 1)); 2871 andl(value, Immediate(kObjectAlignment - 1));
2866 // Compare with the expected bit pattern. 2872 // Compare with the expected bit pattern.
2867 cmpl(value, Immediate( 2873 cmpl(value, Immediate(
2868 (kNewObjectAlignmentOffset >> 1) + kHeapObjectTag + 2874 (kNewObjectAlignmentOffset >> 1) + kHeapObjectTag +
2869 kOldObjectAlignmentOffset + kHeapObjectTag)); 2875 kOldObjectAlignmentOffset + kHeapObjectTag));
2870 j(NOT_ZERO, no_update, Assembler::kNearJump); 2876 j(NOT_ZERO, no_update, Assembler::kNearJump);
2871 } 2877 }
2872 2878
2873 2879
2880 void Assembler::Verify(const Address& dest) {
Ivan Posva 2014/11/14 22:16:06 ditto about the name.
koda 2014/11/17 17:08:59 Done, matching ia32.
2881 if (VerifiedMemory::enabled()) {
2882 Register dest_addr = RDX;
2883 Register old_value = RBX;
2884 pushq(dest_addr);
2885 pushq(old_value);
2886 leaq(dest_addr, dest);
2887 movq(old_value, Address(dest_addr, 0));
2888 cmpq(old_value, Address(dest_addr, VerifiedMemory::offset()));
2889 Label ok;
2890 j(EQUAL, &ok, Assembler::kNearJump);
Ivan Posva 2014/11/14 22:16:07 Will be a forced far jump.
koda 2014/11/17 17:09:00 Good point; removed hint.
2891 Stop("Write barrier verification failed");
2892 Bind(&ok);
2893 popq(old_value);
2894 popq(dest_addr);
2895 }
2896 }
2897
2898
2899 void Assembler::VerifiedWrite(const Address& dest, Register value) {
2900 Verify(dest);
2901 movq(dest, value);
2902 if (VerifiedMemory::enabled()) {
2903 Register temp = (value == RDX) ? RCX : RDX;
2904 pushq(temp);
2905 leaq(temp, dest);
2906 movq(Address(temp, VerifiedMemory::offset()), value);
2907 popq(temp);
2908 }
2909 }
2910
2911
2874 void Assembler::StoreIntoObject(Register object, 2912 void Assembler::StoreIntoObject(Register object,
2875 const Address& dest, 2913 const Address& dest,
2876 Register value, 2914 Register value,
2877 bool can_value_be_smi) { 2915 bool can_value_be_smi) {
2878 ASSERT(object != value); 2916 ASSERT(object != value);
2879 movq(dest, value); 2917 VerifiedWrite(dest, value);
2880 Label done; 2918 Label done;
2881 if (can_value_be_smi) { 2919 if (can_value_be_smi) {
2882 StoreIntoObjectFilter(object, value, &done); 2920 StoreIntoObjectFilter(object, value, &done);
2883 } else { 2921 } else {
2884 StoreIntoObjectFilterNoSmi(object, value, &done); 2922 StoreIntoObjectFilterNoSmi(object, value, &done);
2885 } 2923 }
2886 // A store buffer update is required. 2924 // A store buffer update is required.
2887 if (value != RAX) pushq(RAX); 2925 if (value != RAX) pushq(RAX);
2888 if (object != RAX) { 2926 if (object != RAX) {
2889 movq(RAX, object); 2927 movq(RAX, object);
2890 } 2928 }
2891 StubCode* stub_code = Isolate::Current()->stub_code(); 2929 StubCode* stub_code = Isolate::Current()->stub_code();
2892 Call(&stub_code->UpdateStoreBufferLabel(), PP); 2930 Call(&stub_code->UpdateStoreBufferLabel(), PP);
2893 if (value != RAX) popq(RAX); 2931 if (value != RAX) popq(RAX);
2894 Bind(&done); 2932 Bind(&done);
2895 } 2933 }
2896 2934
2897 2935
2898 void Assembler::StoreIntoObjectNoBarrier(Register object, 2936 void Assembler::StoreIntoObjectNoBarrier(Register object,
2899 const Address& dest, 2937 const Address& dest,
2900 Register value) { 2938 Register value) {
2901 movq(dest, value); 2939 VerifiedWrite(dest, value);
2902 #if defined(DEBUG) 2940 #if defined(DEBUG)
2903 Label done; 2941 Label done;
2904 pushq(value); 2942 pushq(value);
2905 StoreIntoObjectFilter(object, value, &done); 2943 StoreIntoObjectFilter(object, value, &done);
2906 Stop("Store buffer update is required"); 2944 Stop("Store buffer update is required");
2907 Bind(&done); 2945 Bind(&done);
2908 popq(value); 2946 popq(value);
2909 #endif // defined(DEBUG) 2947 #endif // defined(DEBUG)
2910 // No store buffer update. 2948 // No store buffer update.
2911 } 2949 }
2912 2950
2913 2951
2952 void Assembler::StoreIntoSmiField(const Address& dest, Register value) {
2953 VerifiedWrite(dest, value);
2954 #if defined(DEBUG)
2955 Label done;
2956 testq(value, Immediate(kHeapObjectTag));
2957 j(ZERO, &done);
2958 Stop("Smi expected");
2959 Bind(&done);
2960 #endif // defined(DEBUG)
2961 }
2962
2963
2964 void Assembler::ZeroSmiField(const Address& dest) {
2965 Verify(dest); // TODO(koda): Add VerifySmi once we distinguish initalization.
2966 Immediate zero(Smi::RawValue(0));
2967 movq(dest, zero);
2968 if (VerifiedMemory::enabled()) {
2969 Register temp = RCX;
2970 pushq(temp);
2971 leaq(temp, dest);
2972 movq(Address(temp, VerifiedMemory::offset()), zero);
2973 popq(temp);
2974 }
2975 }
2976
2977
2978 void Assembler::IncrementSmiField(const Address& dest, int64_t increment) {
2979 // Note: FlowGraphCompiler::EdgeCounterIncrementSizeInBytes depends on
2980 // the length of this instruction sequence.
2981 Verify(dest); // TODO(koda): Add VerifySmi once we distinguish initalization.
2982 Immediate inc_imm(Smi::RawValue(increment));
2983 addq(dest, inc_imm);
2984 if (VerifiedMemory::enabled()) {
2985 Register temp = RCX;
2986 pushq(temp);
2987 leaq(temp, dest);
2988 addq(Address(temp, VerifiedMemory::offset()), inc_imm);
2989 popq(temp);
2990 }
2991 }
2992
2993
2914 void Assembler::DoubleNegate(XmmRegister d) { 2994 void Assembler::DoubleNegate(XmmRegister d) {
2915 static const struct ALIGN16 { 2995 static const struct ALIGN16 {
2916 uint64_t a; 2996 uint64_t a;
2917 uint64_t b; 2997 uint64_t b;
2918 } double_negate_constant = 2998 } double_negate_constant =
2919 {0x8000000000000000LL, 0x8000000000000000LL}; 2999 {0x8000000000000000LL, 0x8000000000000000LL};
2920 LoadImmediate( 3000 LoadImmediate(
2921 TMP, Immediate(reinterpret_cast<intptr_t>(&double_negate_constant)), PP); 3001 TMP, Immediate(reinterpret_cast<intptr_t>(&double_negate_constant)), PP);
2922 xorpd(d, Address(TMP, 0)); 3002 xorpd(d, Address(TMP, 0));
2923 } 3003 }
(...skipping 739 matching lines...) Expand 10 before | Expand all | Expand 10 after
3663 3743
3664 3744
3665 const char* Assembler::FpuRegisterName(FpuRegister reg) { 3745 const char* Assembler::FpuRegisterName(FpuRegister reg) {
3666 ASSERT((0 <= reg) && (reg < kNumberOfXmmRegisters)); 3746 ASSERT((0 <= reg) && (reg < kNumberOfXmmRegisters));
3667 return xmm_reg_names[reg]; 3747 return xmm_reg_names[reg];
3668 } 3748 }
3669 3749
3670 } // namespace dart 3750 } // namespace dart
3671 3751
3672 #endif // defined TARGET_ARCH_X64 3752 #endif // defined TARGET_ARCH_X64
OLDNEW
« no previous file with comments | « runtime/vm/assembler_x64.h ('k') | runtime/vm/code_patcher_x64.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698