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

Side by Side Diff: src/x64/lithium-codegen-x64.cc

Issue 316023002: --debug-code: sanity-checking instrumentation for Lithium object accesses (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: addressed Igor's comments Created 6 years, 6 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/x64/lithium-codegen-x64.h ('k') | no next file » | 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 // 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/v8.h" 5 #include "src/v8.h"
6 6
7 #if V8_TARGET_ARCH_X64 7 #if V8_TARGET_ARCH_X64
8 8
9 #include "src/x64/lithium-codegen-x64.h" 9 #include "src/x64/lithium-codegen-x64.h"
10 #include "src/code-stubs.h" 10 #include "src/code-stubs.h"
(...skipping 2876 matching lines...) Expand 10 before | Expand all | Expand 10 after
2887 scratch, 2887 scratch,
2888 kSaveFPRegs, 2888 kSaveFPRegs,
2889 EMIT_REMEMBERED_SET, 2889 EMIT_REMEMBERED_SET,
2890 check_needed); 2890 check_needed);
2891 } 2891 }
2892 2892
2893 __ bind(&skip_assignment); 2893 __ bind(&skip_assignment);
2894 } 2894 }
2895 2895
2896 2896
2897 #ifdef DEBUG
2898 void LCodeGen::EmitCheckMap(Register object, Handle<Map> map) {
2899 __ CompareMap(object, map);
2900 __ Check(equal, kObjectAccessCheckFailed);
2901 }
2902
2903
2904 void LCodeGen::EmitCheckInstanceType(Register object, InstanceType type,
2905 Condition condition) {
2906 __ movp(kScratchRegister, FieldOperand(object, HeapObject::kMapOffset));
2907 __ CmpInstanceType(kScratchRegister, type);
2908 __ Check(condition, kObjectAccessCheckFailed);
2909 }
2910
2911
2912 void LCodeGen::EmitObjectAccessVerification(HObjectAccess* access,
2913 Register object,
2914 bool is_store) {
2915 if (!FLAG_debug_code) return;
2916 Comment(";;; HObjectAccess check <%d>", static_cast<int>(access->purpose()));
2917 switch (access->purpose()) {
2918 case HObjectAccess::FOR_HEAP_NUMBER_VALUE:
2919 case HObjectAccess::FOR_HEAP_NUMBER_VALUE_HIGHEST_BITS:
2920 case HObjectAccess::FOR_HEAP_NUMBER_VALUE_LOWEST_BITS:
2921 EmitCheckMap(object, isolate()->factory()->heap_number_map());
2922 break;
2923
2924 case HObjectAccess::FOR_ALLOCATION_MEMENTO_SITE:
2925 EmitCheckMap(object, isolate()->factory()->allocation_memento_map());
2926 break;
2927
2928 case HObjectAccess::FOR_ALLOCATION_SITE_OFFSET:
2929 EmitCheckMap(object, isolate()->factory()->allocation_site_map());
2930 break;
2931
2932 case HObjectAccess::FOR_CODE_OFFSET:
2933 case HObjectAccess::FOR_OPTIMIZED_CODE_MAP:
2934 EmitCheckMap(object, isolate()->factory()->shared_function_info_map());
2935 break;
2936
2937 case HObjectAccess::FOR_MAP_INSTANCE_SIZE:
2938 case HObjectAccess::FOR_MAP_INSTANCE_TYPE:
2939 EmitCheckMap(object, isolate()->factory()->meta_map());
2940 break;
2941
2942 case HObjectAccess::FOR_CELL_VALUE:
2943 case HObjectAccess::FOR_PROPERTY_CELL_VALUE:
2944 EmitCheckMap(object, isolate()->factory()->cell_map());
2945 break;
2946
2947 case HObjectAccess::FOR_CONTEXT_SLOT:
2948 EmitCheckInstanceType(object, FIXED_ARRAY_TYPE);
2949 break;
2950
2951 case HObjectAccess::FOR_CODE_ENTRY_POINTER:
2952 case HObjectAccess::FOR_FUNCTION_CONTEXT_POINTER:
2953 case HObjectAccess::FOR_LITERALS_POINTER:
2954 case HObjectAccess::FOR_NEXT_FUNCTION_LINK_POINTER:
2955 case HObjectAccess::FOR_PROTOTYPE_OR_INITIAL_MAP:
2956 case HObjectAccess::FOR_SHARED_FUNCTION_INFO_POINTER:
2957 EmitCheckInstanceType(object, JS_FUNCTION_TYPE);
2958 break;
2959
2960 case HObjectAccess::FOR_ARRAY_LENGTH:
2961 case HObjectAccess::FOR_JSARRAY_OFFSET:
2962 EmitCheckInstanceType(object, JS_ARRAY_TYPE);
2963 break;
2964
2965 case HObjectAccess::FOR_JSTYPEDARRAY_LENGTH:
2966 EmitCheckInstanceType(object, JS_TYPED_ARRAY_TYPE);
2967 break;
2968
2969 case HObjectAccess::FOR_JSARRAYBUFFER_BACKING_STORE:
2970 case HObjectAccess::FOR_JSARRAYBUFFER_BYTE_LENGTH:
2971 case HObjectAccess::FOR_JSARRAYBUFFER_WEAK_FIRST_VIEW:
2972 EmitCheckInstanceType(object, JS_ARRAY_BUFFER_TYPE);
2973 break;
2974
2975 case HObjectAccess::FOR_STRING_HASH_FIELD:
2976 case HObjectAccess::FOR_STRING_LENGTH:
2977 EmitCheckInstanceType(object, FIRST_NONSTRING_TYPE, below);
2978 break;
2979
2980 case HObjectAccess::FOR_ELEMENTS_POINTER:
2981 case HObjectAccess::FOR_PROPERTIES_POINTER:
2982 EmitCheckInstanceType(object, FIRST_JS_OBJECT_TYPE, above_equal);
2983 break;
2984
2985 case HObjectAccess::FOR_JSARRAYBUFFERVIEW_BUFFER:
2986 case HObjectAccess::FOR_JSARRAYBUFFERVIEW_BYTE_LENGTH:
2987 case HObjectAccess::FOR_JSARRAYBUFFERVIEW_BYTE_OFFSET:
2988 case HObjectAccess::FOR_JSARRAYBUFFERVIEW_WEAK_NEXT: {
2989 Label ok;
2990 __ movp(kScratchRegister, FieldOperand(object, HeapObject::kMapOffset));
2991 __ CmpInstanceType(kScratchRegister, JS_TYPED_ARRAY_TYPE);
2992 __ j(equal, &ok, Label::kNear);
2993 __ CmpInstanceType(kScratchRegister, JS_DATA_VIEW_TYPE);
2994 __ j(equal, &ok, Label::kNear);
2995 __ Abort(kObjectAccessCheckFailed);
2996 __ bind(&ok);
2997 break;
2998 }
2999 case HObjectAccess::FOR_EXTERNAL_ARRAY_EXTERNAL_POINTER: {
3000 Label ok, bad;
3001 __ movp(kScratchRegister, FieldOperand(object, HeapObject::kMapOffset));
3002 __ CmpInstanceType(kScratchRegister, FIRST_EXTERNAL_ARRAY_TYPE);
3003 __ j(below, &bad, Label::kNear);
3004 __ CmpInstanceType(kScratchRegister, LAST_EXTERNAL_ARRAY_TYPE);
3005 __ j(below_equal, &ok, Label::kNear);
3006 __ bind(&bad);
3007 __ Abort(kObjectAccessCheckFailed);
3008 __ bind(&ok);
3009 break;
3010 }
3011 case HObjectAccess::FOR_FIXED_ARRAY_HEADER:
3012 if (access->offset() == 0) break; // Setting the map.
3013 // Else fall through.
3014 case HObjectAccess::FOR_FIXED_ARRAY_LENGTH: {
3015 Label ok, bad;
3016 __ movp(kScratchRegister, FieldOperand(object, HeapObject::kMapOffset));
3017 __ CmpInstanceType(kScratchRegister, FIRST_FIXED_ARRAY_TYPE);
3018 __ j(below, &bad, Label::kNear);
3019 __ CmpInstanceType(kScratchRegister, LAST_FIXED_ARRAY_TYPE);
3020 __ j(below_equal, &ok, Label::kNear);
3021 __ bind(&bad);
3022 __ Abort(kObjectAccessCheckFailed);
3023 __ bind(&ok);
3024 break;
3025 }
3026 case HObjectAccess::FOR_CONS_STRING_FIRST:
3027 case HObjectAccess::FOR_CONS_STRING_SECOND: {
3028 Label ok;
3029 __ CompareMap(object, isolate()->factory()->cons_string_map());
3030 __ j(equal, &ok, Label::kNear);
3031 __ CompareMap(object, isolate()->factory()->cons_ascii_string_map());
3032 __ j(equal, &ok, Label::kNear);
3033 __ Abort(kObjectAccessCheckFailed);
3034 __ bind(&ok);
3035 break;
3036 }
3037
3038 case HObjectAccess::FOR_CELL_PAYLOAD: {
3039 Label ok;
3040 __ CompareMap(object, isolate()->factory()->cell_map());
3041 __ j(equal, &ok, Label::kNear);
3042 __ CompareMap(object, isolate()->factory()->global_property_cell_map());
3043 __ j(equal, &ok, Label::kNear);
3044 __ Abort(kObjectAccessCheckFailed);
3045 __ bind(&ok);
3046 break;
3047 }
3048
3049 case HObjectAccess::FOR_BACKING_STORE_OFFSET: {
3050 ASSERT(!access->IsInobject());
3051 // Load backing store.
3052 __ movp(kScratchRegister,
3053 FieldOperand(object, JSObject::kPropertiesOffset));
3054 // Load backing store length, with implicit Smi untagging.
3055 STATIC_ASSERT(kSmiTagSize + kSmiShiftSize == 32);
3056 __ movl(kScratchRegister,
3057 FieldOperand(kScratchRegister,
3058 FixedArray::kLengthOffset + kPointerSize / 2));
3059 // The loaded length does not include the backing store's header size,
3060 // but access->offset() does.
3061 ASSERT(access->offset() >= FixedArray::kHeaderSize);
3062 int accessed_index =
3063 (access->offset() - FixedArray::kHeaderSize) / kPointerSize;
3064 __ cmpl(kScratchRegister, Immediate(accessed_index));
3065 __ Check(above, kObjectAccessCheckFailed);
3066 break;
3067 }
3068 case HObjectAccess::FOR_FIELD: {
3069 ASSERT(access->IsInobject());
3070 Label ok;
3071 __ movp(kScratchRegister, FieldOperand(object, HeapObject::kMapOffset));
3072 // Some objects have variable instance size (e.g. FixedArray).
3073 // To check those, we'd need an equivalent of HeapObject::SizeFromMap.
3074 // For now we just skip such objects.
3075 __ cmpb(FieldOperand(kScratchRegister, Map::kInstanceSizeOffset),
3076 Immediate(kVariableSizeSentinel));
3077 __ j(equal, &ok, Label::kNear);
3078
3079 __ cmpb(FieldOperand(kScratchRegister, Map::kInstanceSizeOffset),
3080 Immediate(access->offset() / kPointerSize));
3081 __ Check(above, kObjectAccessCheckFailed);
3082 __ bind(&ok);
3083 break;
3084 }
3085 case HObjectAccess::FOR_GLOBAL_OBJECT_NATIVE_CONTEXT:
3086 case HObjectAccess::FOR_MAP:
3087 // Unimplemented. That's OK for now.
3088 break;
3089
3090 case HObjectAccess::FOR_ALLOCATION_SITE_LIST:
3091 case HObjectAccess::FOR_COUNTER:
3092 // External. Handled differently.
3093 case HObjectAccess::UNKNOWN_PURPOSE:
3094 // Don't use UNKNOWN_PURPOSE.
3095 UNREACHABLE();
3096 break;
3097 }
3098 }
3099 #endif
3100
3101
2897 void LCodeGen::DoLoadNamedField(LLoadNamedField* instr) { 3102 void LCodeGen::DoLoadNamedField(LLoadNamedField* instr) {
2898 HObjectAccess access = instr->hydrogen()->access(); 3103 HObjectAccess access = instr->hydrogen()->access();
2899 int offset = access.offset(); 3104 int offset = access.offset();
2900 3105
2901 if (access.IsExternalMemory()) { 3106 if (access.IsExternalMemory()) {
2902 Register result = ToRegister(instr->result()); 3107 Register result = ToRegister(instr->result());
2903 if (instr->object()->IsConstantOperand()) { 3108 if (instr->object()->IsConstantOperand()) {
2904 ASSERT(result.is(rax)); 3109 ASSERT(result.is(rax));
2905 __ load_rax(ToExternalReference(LConstantOperand::cast(instr->object()))); 3110 __ load_rax(ToExternalReference(LConstantOperand::cast(instr->object())));
2906 } else { 3111 } else {
2907 Register object = ToRegister(instr->object()); 3112 Register object = ToRegister(instr->object());
2908 __ Load(result, MemOperand(object, offset), access.representation()); 3113 __ Load(result, MemOperand(object, offset), access.representation());
2909 } 3114 }
2910 return; 3115 return;
2911 } 3116 }
2912 3117
2913 Register object = ToRegister(instr->object()); 3118 Register object = ToRegister(instr->object());
3119 #ifdef DEBUG
3120 EmitObjectAccessVerification(&access, object, false);
3121 #endif
2914 if (instr->hydrogen()->representation().IsDouble()) { 3122 if (instr->hydrogen()->representation().IsDouble()) {
2915 XMMRegister result = ToDoubleRegister(instr->result()); 3123 XMMRegister result = ToDoubleRegister(instr->result());
2916 __ movsd(result, FieldOperand(object, offset)); 3124 __ movsd(result, FieldOperand(object, offset));
2917 return; 3125 return;
2918 } 3126 }
2919 3127
2920 Register result = ToRegister(instr->result()); 3128 Register result = ToRegister(instr->result());
2921 if (!access.IsInobject()) { 3129 if (!access.IsInobject()) {
2922 __ movp(result, FieldOperand(object, JSObject::kPropertiesOffset)); 3130 __ movp(result, FieldOperand(object, JSObject::kPropertiesOffset));
2923 object = result; 3131 object = result;
(...skipping 100 matching lines...) Expand 10 before | Expand all | Expand 10 after
3024 } else { 3232 } else {
3025 __ subl(length, ToOperand(instr->index())); 3233 __ subl(length, ToOperand(instr->index()));
3026 } 3234 }
3027 StackArgumentsAccessor args(arguments, length, 3235 StackArgumentsAccessor args(arguments, length,
3028 ARGUMENTS_DONT_CONTAIN_RECEIVER); 3236 ARGUMENTS_DONT_CONTAIN_RECEIVER);
3029 __ movp(result, args.GetArgumentOperand(0)); 3237 __ movp(result, args.GetArgumentOperand(0));
3030 } 3238 }
3031 } 3239 }
3032 3240
3033 3241
3242 #ifdef DEBUG
3243 void LCodeGen::EmitKeyedAccessVerification(LOperand* elements,
3244 Operand operand) {
3245 if (!FLAG_debug_code) return;
3246 Register elements_reg = ToRegister(elements);
3247 Register length_scratch = kScratchRegister;
3248 Register access_scratch = r11;
3249 __ Push(access_scratch);
3250 // 64-bit platforms make it easy :-)
3251 STATIC_ASSERT(kPointerSize == kDoubleSize);
3252 const int kHeaderSize = FixedArrayBase::kHeaderSize;
3253 STATIC_ASSERT(kHeaderSize == FixedArray::kHeaderSize);
3254 STATIC_ASSERT(kHeaderSize == FixedDoubleArray::kHeaderSize);
3255 STATIC_ASSERT(kHeaderSize == FixedTypedArrayBase::kHeaderSize);
3256
3257 // Load elements length, with implicit Smi untagging.
3258 STATIC_ASSERT(kSmiTagSize + kSmiShiftSize == 32);
3259 __ movl(length_scratch,
3260 FieldOperand(elements_reg,
3261 FixedArrayBase::kLengthOffset + kPointerSize / 2));
3262 // Multiply with pointer size and add header size to get the object length.
3263 __ leaq(length_scratch,
3264 Operand(length_scratch, times_pointer_size,
3265 kHeaderSize - kHeapObjectTag));
3266 // Compute the actually accessed offset in access_scratch.
3267 __ leaq(access_scratch, operand);
3268 __ subq(access_scratch, elements_reg);
3269 __ cmpq(length_scratch, access_scratch);
3270 __ Check(above, kObjectAccessCheckFailed);
3271 __ Pop(access_scratch);
3272 }
3273 #endif
3274
3275
3034 void LCodeGen::DoLoadKeyedExternalArray(LLoadKeyed* instr) { 3276 void LCodeGen::DoLoadKeyedExternalArray(LLoadKeyed* instr) {
3035 ElementsKind elements_kind = instr->elements_kind(); 3277 ElementsKind elements_kind = instr->elements_kind();
3036 LOperand* key = instr->key(); 3278 LOperand* key = instr->key();
3037 Operand operand(BuildFastArrayOperand( 3279 Operand operand(BuildFastArrayOperand(
3038 instr->elements(), 3280 instr->elements(),
3039 key, 3281 key,
3040 elements_kind, 3282 elements_kind,
3041 instr->base_offset())); 3283 instr->base_offset()));
3042 3284
3285 #ifdef DEBUG
3286 // TODO(jkummerow): Support external elements too.
3287 if (!IsExternalArrayElementsKind(elements_kind)) {
3288 EmitKeyedAccessVerification(instr->elements(), operand);
3289 }
3290 #endif
3291
3043 if (elements_kind == EXTERNAL_FLOAT32_ELEMENTS || 3292 if (elements_kind == EXTERNAL_FLOAT32_ELEMENTS ||
3044 elements_kind == FLOAT32_ELEMENTS) { 3293 elements_kind == FLOAT32_ELEMENTS) {
3045 XMMRegister result(ToDoubleRegister(instr->result())); 3294 XMMRegister result(ToDoubleRegister(instr->result()));
3046 __ movss(result, operand); 3295 __ movss(result, operand);
3047 __ cvtss2sd(result, result); 3296 __ cvtss2sd(result, result);
3048 } else if (elements_kind == EXTERNAL_FLOAT64_ELEMENTS || 3297 } else if (elements_kind == EXTERNAL_FLOAT64_ELEMENTS ||
3049 elements_kind == FLOAT64_ELEMENTS) { 3298 elements_kind == FLOAT64_ELEMENTS) {
3050 __ movsd(ToDoubleRegister(instr->result()), operand); 3299 __ movsd(ToDoubleRegister(instr->result()), operand);
3051 } else { 3300 } else {
3052 Register result(ToRegister(instr->result())); 3301 Register result(ToRegister(instr->result()));
(...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after
3111 instr->base_offset() + sizeof(kHoleNanLower32)); 3360 instr->base_offset() + sizeof(kHoleNanLower32));
3112 __ cmpl(hole_check_operand, Immediate(kHoleNanUpper32)); 3361 __ cmpl(hole_check_operand, Immediate(kHoleNanUpper32));
3113 DeoptimizeIf(equal, instr->environment()); 3362 DeoptimizeIf(equal, instr->environment());
3114 } 3363 }
3115 3364
3116 Operand double_load_operand = BuildFastArrayOperand( 3365 Operand double_load_operand = BuildFastArrayOperand(
3117 instr->elements(), 3366 instr->elements(),
3118 key, 3367 key,
3119 FAST_DOUBLE_ELEMENTS, 3368 FAST_DOUBLE_ELEMENTS,
3120 instr->base_offset()); 3369 instr->base_offset());
3370 #ifdef DEBUG
3371 EmitKeyedAccessVerification(instr->elements(), double_load_operand);
3372 #endif
3121 __ movsd(result, double_load_operand); 3373 __ movsd(result, double_load_operand);
3122 } 3374 }
3123 3375
3124 3376
3125 void LCodeGen::DoLoadKeyedFixedArray(LLoadKeyed* instr) { 3377 void LCodeGen::DoLoadKeyedFixedArray(LLoadKeyed* instr) {
3126 HLoadKeyed* hinstr = instr->hydrogen(); 3378 HLoadKeyed* hinstr = instr->hydrogen();
3127 Register result = ToRegister(instr->result()); 3379 Register result = ToRegister(instr->result());
3128 LOperand* key = instr->key(); 3380 LOperand* key = instr->key();
3129 bool requires_hole_check = hinstr->RequiresHoleCheck(); 3381 bool requires_hole_check = hinstr->RequiresHoleCheck();
3130 Representation representation = hinstr->representation(); 3382 Representation representation = hinstr->representation();
(...skipping 11 matching lines...) Expand all
3142 offset), 3394 offset),
3143 Representation::Smi()); 3395 Representation::Smi());
3144 __ AssertSmi(scratch); 3396 __ AssertSmi(scratch);
3145 } 3397 }
3146 // Read int value directly from upper half of the smi. 3398 // Read int value directly from upper half of the smi.
3147 STATIC_ASSERT(kSmiTag == 0); 3399 STATIC_ASSERT(kSmiTag == 0);
3148 ASSERT(kSmiTagSize + kSmiShiftSize == 32); 3400 ASSERT(kSmiTagSize + kSmiShiftSize == 32);
3149 offset += kPointerSize / 2; 3401 offset += kPointerSize / 2;
3150 } 3402 }
3151 3403
3152 __ Load(result, 3404 Operand operand = BuildFastArrayOperand(instr->elements(),
3153 BuildFastArrayOperand(instr->elements(), 3405 key,
3154 key, 3406 FAST_ELEMENTS,
3155 FAST_ELEMENTS, 3407 offset);
3156 offset), 3408 #ifdef DEBUG
3157 representation); 3409 EmitKeyedAccessVerification(instr->elements(), operand);
3410 #endif
3411 __ Load(result, operand, representation);
3158 3412
3159 // Check for the hole value. 3413 // Check for the hole value.
3160 if (requires_hole_check) { 3414 if (requires_hole_check) {
3161 if (IsFastSmiElementsKind(hinstr->elements_kind())) { 3415 if (IsFastSmiElementsKind(hinstr->elements_kind())) {
3162 Condition smi = __ CheckSmi(result); 3416 Condition smi = __ CheckSmi(result);
3163 DeoptimizeIf(NegateCondition(smi), instr->environment()); 3417 DeoptimizeIf(NegateCondition(smi), instr->environment());
3164 } else { 3418 } else {
3165 __ CompareRoot(result, Heap::kTheHoleValueRootIndex); 3419 __ CompareRoot(result, Heap::kTheHoleValueRootIndex);
3166 DeoptimizeIf(equal, instr->environment()); 3420 DeoptimizeIf(equal, instr->environment());
3167 } 3421 }
(...skipping 826 matching lines...) Expand 10 before | Expand all | Expand 10 after
3994 __ store_rax(ToExternalReference(object)); 4248 __ store_rax(ToExternalReference(object));
3995 } else { 4249 } else {
3996 Register object = ToRegister(instr->object()); 4250 Register object = ToRegister(instr->object());
3997 __ Store(MemOperand(object, offset), value, representation); 4251 __ Store(MemOperand(object, offset), value, representation);
3998 } 4252 }
3999 return; 4253 return;
4000 } 4254 }
4001 4255
4002 Register object = ToRegister(instr->object()); 4256 Register object = ToRegister(instr->object());
4003 __ AssertNotSmi(object); 4257 __ AssertNotSmi(object);
4258 #ifdef DEBUG
4259 EmitObjectAccessVerification(&access, object, true);
4260 #endif
4004 4261
4005 ASSERT(!representation.IsSmi() || 4262 ASSERT(!representation.IsSmi() ||
4006 !instr->value()->IsConstantOperand() || 4263 !instr->value()->IsConstantOperand() ||
4007 IsInteger32Constant(LConstantOperand::cast(instr->value()))); 4264 IsInteger32Constant(LConstantOperand::cast(instr->value())));
4008 if (representation.IsDouble()) { 4265 if (representation.IsDouble()) {
4009 ASSERT(access.IsInobject()); 4266 ASSERT(access.IsInobject());
4010 ASSERT(!hinstr->has_transition()); 4267 ASSERT(!hinstr->has_transition());
4011 ASSERT(!hinstr->NeedsWriteBarrier()); 4268 ASSERT(!hinstr->NeedsWriteBarrier());
4012 XMMRegister value = ToDoubleRegister(instr->value()); 4269 XMMRegister value = ToDoubleRegister(instr->value());
4013 __ movsd(FieldOperand(object, offset), value); 4270 __ movsd(FieldOperand(object, offset), value);
(...skipping 153 matching lines...) Expand 10 before | Expand all | Expand 10 after
4167 4424
4168 void LCodeGen::DoStoreKeyedExternalArray(LStoreKeyed* instr) { 4425 void LCodeGen::DoStoreKeyedExternalArray(LStoreKeyed* instr) {
4169 ElementsKind elements_kind = instr->elements_kind(); 4426 ElementsKind elements_kind = instr->elements_kind();
4170 LOperand* key = instr->key(); 4427 LOperand* key = instr->key();
4171 Operand operand(BuildFastArrayOperand( 4428 Operand operand(BuildFastArrayOperand(
4172 instr->elements(), 4429 instr->elements(),
4173 key, 4430 key,
4174 elements_kind, 4431 elements_kind,
4175 instr->base_offset())); 4432 instr->base_offset()));
4176 4433
4434 #ifdef DEBUG
4435 if (!IsExternalArrayElementsKind(elements_kind)) {
4436 EmitKeyedAccessVerification(instr->elements(), operand);
4437 }
4438 #endif
4439
4177 if (elements_kind == EXTERNAL_FLOAT32_ELEMENTS || 4440 if (elements_kind == EXTERNAL_FLOAT32_ELEMENTS ||
4178 elements_kind == FLOAT32_ELEMENTS) { 4441 elements_kind == FLOAT32_ELEMENTS) {
4179 XMMRegister value(ToDoubleRegister(instr->value())); 4442 XMMRegister value(ToDoubleRegister(instr->value()));
4180 __ cvtsd2ss(value, value); 4443 __ cvtsd2ss(value, value);
4181 __ movss(operand, value); 4444 __ movss(operand, value);
4182 } else if (elements_kind == EXTERNAL_FLOAT64_ELEMENTS || 4445 } else if (elements_kind == EXTERNAL_FLOAT64_ELEMENTS ||
4183 elements_kind == FLOAT64_ELEMENTS) { 4446 elements_kind == FLOAT64_ELEMENTS) {
4184 __ movsd(operand, ToDoubleRegister(instr->value())); 4447 __ movsd(operand, ToDoubleRegister(instr->value()));
4185 } else { 4448 } else {
4186 Register value(ToRegister(instr->value())); 4449 Register value(ToRegister(instr->value()));
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after
4238 __ movq(value, kScratchRegister); 4501 __ movq(value, kScratchRegister);
4239 4502
4240 __ bind(&have_value); 4503 __ bind(&have_value);
4241 } 4504 }
4242 4505
4243 Operand double_store_operand = BuildFastArrayOperand( 4506 Operand double_store_operand = BuildFastArrayOperand(
4244 instr->elements(), 4507 instr->elements(),
4245 key, 4508 key,
4246 FAST_DOUBLE_ELEMENTS, 4509 FAST_DOUBLE_ELEMENTS,
4247 instr->base_offset()); 4510 instr->base_offset());
4248 4511 #ifdef DEBUG
4512 EmitKeyedAccessVerification(instr->elements(), double_store_operand);
4513 #endif
4249 __ movsd(double_store_operand, value); 4514 __ movsd(double_store_operand, value);
4250 } 4515 }
4251 4516
4252 4517
4253 void LCodeGen::DoStoreKeyedFixedArray(LStoreKeyed* instr) { 4518 void LCodeGen::DoStoreKeyedFixedArray(LStoreKeyed* instr) {
4254 HStoreKeyed* hinstr = instr->hydrogen(); 4519 HStoreKeyed* hinstr = instr->hydrogen();
4255 LOperand* key = instr->key(); 4520 LOperand* key = instr->key();
4256 int offset = instr->base_offset(); 4521 int offset = instr->base_offset();
4257 Representation representation = hinstr->value()->representation(); 4522 Representation representation = hinstr->value()->representation();
4258 4523
(...skipping 14 matching lines...) Expand all
4273 STATIC_ASSERT(kSmiTag == 0); 4538 STATIC_ASSERT(kSmiTag == 0);
4274 ASSERT(kSmiTagSize + kSmiShiftSize == 32); 4539 ASSERT(kSmiTagSize + kSmiShiftSize == 32);
4275 offset += kPointerSize / 2; 4540 offset += kPointerSize / 2;
4276 } 4541 }
4277 4542
4278 Operand operand = 4543 Operand operand =
4279 BuildFastArrayOperand(instr->elements(), 4544 BuildFastArrayOperand(instr->elements(),
4280 key, 4545 key,
4281 FAST_ELEMENTS, 4546 FAST_ELEMENTS,
4282 offset); 4547 offset);
4548 #ifdef DEBUG
4549 EmitKeyedAccessVerification(instr->elements(), operand);
4550 #endif
4283 if (instr->value()->IsRegister()) { 4551 if (instr->value()->IsRegister()) {
4284 __ Store(operand, ToRegister(instr->value()), representation); 4552 __ Store(operand, ToRegister(instr->value()), representation);
4285 } else { 4553 } else {
4286 LConstantOperand* operand_value = LConstantOperand::cast(instr->value()); 4554 LConstantOperand* operand_value = LConstantOperand::cast(instr->value());
4287 if (IsInteger32Constant(operand_value)) { 4555 if (IsInteger32Constant(operand_value)) {
4288 int32_t value = ToInteger32(operand_value); 4556 int32_t value = ToInteger32(operand_value);
4289 if (representation.IsSmi()) { 4557 if (representation.IsSmi()) {
4290 __ Move(operand, Smi::FromInt(value)); 4558 __ Move(operand, Smi::FromInt(value));
4291 4559
4292 } else { 4560 } else {
(...skipping 1390 matching lines...) Expand 10 before | Expand all | Expand 10 after
5683 __ bind(deferred->exit()); 5951 __ bind(deferred->exit());
5684 __ bind(&done); 5952 __ bind(&done);
5685 } 5953 }
5686 5954
5687 5955
5688 #undef __ 5956 #undef __
5689 5957
5690 } } // namespace v8::internal 5958 } } // namespace v8::internal
5691 5959
5692 #endif // V8_TARGET_ARCH_X64 5960 #endif // V8_TARGET_ARCH_X64
OLDNEW
« no previous file with comments | « src/x64/lithium-codegen-x64.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698