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

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: 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
« src/objects.h ('K') | « 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::EmitObjectAccessChecks(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.
Igor Sheludko 2014/06/05 09:04:30 STATIC_ASSERT(kSmiTagSize + kSmiShiftSize == 32);
Jakob Kummerow 2014/06/05 14:33:31 Done.
3055 __ movl(kScratchRegister,
3056 FieldOperand(kScratchRegister,
3057 FixedArray::kLengthOffset + kPointerSize / 2));
3058 // The loaded length does not include the backing store's header size,
3059 // but access->offset() does.
3060 ASSERT(access->offset() >= FixedArray::kHeaderSize);
3061 int accessed_index =
3062 (access->offset() - FixedArray::kHeaderSize) / kPointerSize;
3063 __ cmpl(kScratchRegister, Immediate(accessed_index));
3064 __ Check(above, kObjectAccessCheckFailed);
3065 break;
3066 }
3067 case HObjectAccess::FOR_FIELD: {
3068 ASSERT(access->IsInobject());
3069 Label ok;
3070 __ movp(kScratchRegister, FieldOperand(object, HeapObject::kMapOffset));
3071 // Some objects have variable instance size (e.g. FixedArray).
3072 // To check those, we'd need an equivalent of HeapObject::SizeFromMap.
3073 // For now we just skip such objects.
3074 __ cmpb(FieldOperand(kScratchRegister, Map::kInstanceSizeOffset),
3075 Immediate(kVariableSizeSentinel));
3076 __ j(equal, &ok, Label::kNear);
3077
3078 __ cmpb(FieldOperand(kScratchRegister, Map::kInstanceSizeOffset),
3079 Immediate(access->offset() / kPointerSize));
3080 __ Check(above, kObjectAccessCheckFailed);
3081 __ bind(&ok);
3082 break;
3083 }
3084 case HObjectAccess::FOR_GLOBAL_OBJECT_NATIVE_CONTEXT:
3085 case HObjectAccess::FOR_MAP:
3086 // Unimplemented. That's OK for now.
3087 break;
3088
3089 case HObjectAccess::FOR_ALLOCATION_SITE_LIST:
3090 case HObjectAccess::FOR_COUNTER:
3091 // External. Handled differently.
3092 case HObjectAccess::UNKNOWN_PURPOSE:
3093 // Don't use UNKNOWN_PURPOSE.
Igor Sheludko 2014/06/05 09:04:30 default:
Jakob Kummerow 2014/06/05 14:33:31 Nope. We generally don't use "default:" cases when
3094 UNREACHABLE();
3095 break;
3096 }
3097 }
3098 #endif
3099
3100
2897 void LCodeGen::DoLoadNamedField(LLoadNamedField* instr) { 3101 void LCodeGen::DoLoadNamedField(LLoadNamedField* instr) {
2898 HObjectAccess access = instr->hydrogen()->access(); 3102 HObjectAccess access = instr->hydrogen()->access();
2899 int offset = access.offset(); 3103 int offset = access.offset();
2900 3104
2901 if (access.IsExternalMemory()) { 3105 if (access.IsExternalMemory()) {
2902 Register result = ToRegister(instr->result()); 3106 Register result = ToRegister(instr->result());
2903 if (instr->object()->IsConstantOperand()) { 3107 if (instr->object()->IsConstantOperand()) {
2904 ASSERT(result.is(rax)); 3108 ASSERT(result.is(rax));
2905 __ load_rax(ToExternalReference(LConstantOperand::cast(instr->object()))); 3109 __ load_rax(ToExternalReference(LConstantOperand::cast(instr->object())));
2906 } else { 3110 } else {
2907 Register object = ToRegister(instr->object()); 3111 Register object = ToRegister(instr->object());
2908 __ Load(result, MemOperand(object, offset), access.representation()); 3112 __ Load(result, MemOperand(object, offset), access.representation());
2909 } 3113 }
2910 return; 3114 return;
2911 } 3115 }
2912 3116
2913 Register object = ToRegister(instr->object()); 3117 Register object = ToRegister(instr->object());
3118 #ifdef DEBUG
3119 EmitObjectAccessChecks(&access, object, false);
3120 #endif
2914 if (instr->hydrogen()->representation().IsDouble()) { 3121 if (instr->hydrogen()->representation().IsDouble()) {
2915 XMMRegister result = ToDoubleRegister(instr->result()); 3122 XMMRegister result = ToDoubleRegister(instr->result());
2916 __ movsd(result, FieldOperand(object, offset)); 3123 __ movsd(result, FieldOperand(object, offset));
2917 return; 3124 return;
2918 } 3125 }
2919 3126
2920 Register result = ToRegister(instr->result()); 3127 Register result = ToRegister(instr->result());
2921 if (!access.IsInobject()) { 3128 if (!access.IsInobject()) {
2922 __ movp(result, FieldOperand(object, JSObject::kPropertiesOffset)); 3129 __ movp(result, FieldOperand(object, JSObject::kPropertiesOffset));
2923 object = result; 3130 object = result;
(...skipping 100 matching lines...) Expand 10 before | Expand all | Expand 10 after
3024 } else { 3231 } else {
3025 __ subl(length, ToOperand(instr->index())); 3232 __ subl(length, ToOperand(instr->index()));
3026 } 3233 }
3027 StackArgumentsAccessor args(arguments, length, 3234 StackArgumentsAccessor args(arguments, length,
3028 ARGUMENTS_DONT_CONTAIN_RECEIVER); 3235 ARGUMENTS_DONT_CONTAIN_RECEIVER);
3029 __ movp(result, args.GetArgumentOperand(0)); 3236 __ movp(result, args.GetArgumentOperand(0));
3030 } 3237 }
3031 } 3238 }
3032 3239
3033 3240
3241 #ifdef DEBUG
3242 void LCodeGen::EmitKeyedAccessCheck(LOperand* elements, Operand operand) {
3243 if (!FLAG_debug_code) return;
3244 Register elements_reg = ToRegister(elements);
3245 Register length_scratch = kScratchRegister;
3246 Register access_scratch = r11;
3247 __ Push(access_scratch);
3248 // 64-bit platforms make it easy :-)
3249 STATIC_ASSERT(kPointerSize == kDoubleSize);
3250 const int kHeaderSize = FixedArrayBase::kHeaderSize;
3251 STATIC_ASSERT(kHeaderSize == FixedArray::kHeaderSize);
3252 STATIC_ASSERT(kHeaderSize == FixedDoubleArray::kHeaderSize);
3253 STATIC_ASSERT(kHeaderSize == FixedTypedArrayBase::kHeaderSize);
3254
3255 // Load elements length, with implicit Smi untagging.
Igor Sheludko 2014/06/05 09:04:30 STATIC_ASSERT(kSmiTagSize + kSmiShiftSize == 32);
Jakob Kummerow 2014/06/05 14:33:31 Done.
3256 __ movl(length_scratch,
3257 FieldOperand(elements_reg,
3258 FixedArrayBase::kLengthOffset + kPointerSize / 2));
3259 // Multiply with pointer size and add header size to get the object length.
3260 __ leaq(length_scratch,
3261 Operand(length_scratch, times_pointer_size,
3262 kHeaderSize - kHeapObjectTag));
3263 // Compute the actually accessed offset in access_scratch.
3264 __ leaq(access_scratch, operand);
3265 __ subq(access_scratch, elements_reg);
3266 __ cmpq(length_scratch, access_scratch);
3267 __ Check(above, kObjectAccessCheckFailed);
3268 __ Pop(access_scratch);
3269 }
3270 #endif
3271
3272
3034 void LCodeGen::DoLoadKeyedExternalArray(LLoadKeyed* instr) { 3273 void LCodeGen::DoLoadKeyedExternalArray(LLoadKeyed* instr) {
3035 ElementsKind elements_kind = instr->elements_kind(); 3274 ElementsKind elements_kind = instr->elements_kind();
3036 LOperand* key = instr->key(); 3275 LOperand* key = instr->key();
3037 Operand operand(BuildFastArrayOperand( 3276 Operand operand(BuildFastArrayOperand(
3038 instr->elements(), 3277 instr->elements(),
3039 key, 3278 key,
3040 elements_kind, 3279 elements_kind,
3041 instr->base_offset())); 3280 instr->base_offset()));
3042 3281
3282 #ifdef DEBUG
3283 // TODO(jkummerow): Support external elements too.
3284 if (!IsExternalArrayElementsKind(elements_kind)) {
3285 EmitKeyedAccessCheck(instr->elements(), operand);
3286 }
3287 #endif
3288
3043 if (elements_kind == EXTERNAL_FLOAT32_ELEMENTS || 3289 if (elements_kind == EXTERNAL_FLOAT32_ELEMENTS ||
3044 elements_kind == FLOAT32_ELEMENTS) { 3290 elements_kind == FLOAT32_ELEMENTS) {
3045 XMMRegister result(ToDoubleRegister(instr->result())); 3291 XMMRegister result(ToDoubleRegister(instr->result()));
3046 __ movss(result, operand); 3292 __ movss(result, operand);
3047 __ cvtss2sd(result, result); 3293 __ cvtss2sd(result, result);
3048 } else if (elements_kind == EXTERNAL_FLOAT64_ELEMENTS || 3294 } else if (elements_kind == EXTERNAL_FLOAT64_ELEMENTS ||
3049 elements_kind == FLOAT64_ELEMENTS) { 3295 elements_kind == FLOAT64_ELEMENTS) {
3050 __ movsd(ToDoubleRegister(instr->result()), operand); 3296 __ movsd(ToDoubleRegister(instr->result()), operand);
3051 } else { 3297 } else {
3052 Register result(ToRegister(instr->result())); 3298 Register result(ToRegister(instr->result()));
(...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after
3111 instr->base_offset() + sizeof(kHoleNanLower32)); 3357 instr->base_offset() + sizeof(kHoleNanLower32));
3112 __ cmpl(hole_check_operand, Immediate(kHoleNanUpper32)); 3358 __ cmpl(hole_check_operand, Immediate(kHoleNanUpper32));
3113 DeoptimizeIf(equal, instr->environment()); 3359 DeoptimizeIf(equal, instr->environment());
3114 } 3360 }
3115 3361
3116 Operand double_load_operand = BuildFastArrayOperand( 3362 Operand double_load_operand = BuildFastArrayOperand(
3117 instr->elements(), 3363 instr->elements(),
3118 key, 3364 key,
3119 FAST_DOUBLE_ELEMENTS, 3365 FAST_DOUBLE_ELEMENTS,
3120 instr->base_offset()); 3366 instr->base_offset());
3367 #ifdef DEBUG
3368 EmitKeyedAccessCheck(instr->elements(), double_load_operand);
3369 #endif
3121 __ movsd(result, double_load_operand); 3370 __ movsd(result, double_load_operand);
3122 } 3371 }
3123 3372
3124 3373
3125 void LCodeGen::DoLoadKeyedFixedArray(LLoadKeyed* instr) { 3374 void LCodeGen::DoLoadKeyedFixedArray(LLoadKeyed* instr) {
3126 HLoadKeyed* hinstr = instr->hydrogen(); 3375 HLoadKeyed* hinstr = instr->hydrogen();
3127 Register result = ToRegister(instr->result()); 3376 Register result = ToRegister(instr->result());
3128 LOperand* key = instr->key(); 3377 LOperand* key = instr->key();
3129 bool requires_hole_check = hinstr->RequiresHoleCheck(); 3378 bool requires_hole_check = hinstr->RequiresHoleCheck();
3130 Representation representation = hinstr->representation(); 3379 Representation representation = hinstr->representation();
(...skipping 11 matching lines...) Expand all
3142 offset), 3391 offset),
3143 Representation::Smi()); 3392 Representation::Smi());
3144 __ AssertSmi(scratch); 3393 __ AssertSmi(scratch);
3145 } 3394 }
3146 // Read int value directly from upper half of the smi. 3395 // Read int value directly from upper half of the smi.
3147 STATIC_ASSERT(kSmiTag == 0); 3396 STATIC_ASSERT(kSmiTag == 0);
3148 ASSERT(kSmiTagSize + kSmiShiftSize == 32); 3397 ASSERT(kSmiTagSize + kSmiShiftSize == 32);
3149 offset += kPointerSize / 2; 3398 offset += kPointerSize / 2;
3150 } 3399 }
3151 3400
3152 __ Load(result, 3401 Operand operand = BuildFastArrayOperand(instr->elements(),
3153 BuildFastArrayOperand(instr->elements(), 3402 key,
3154 key, 3403 FAST_ELEMENTS,
3155 FAST_ELEMENTS, 3404 offset);
3156 offset), 3405 #ifdef DEBUG
3157 representation); 3406 EmitKeyedAccessCheck(instr->elements(), operand);
3407 #endif
3408 __ Load(result, operand, representation);
3158 3409
3159 // Check for the hole value. 3410 // Check for the hole value.
3160 if (requires_hole_check) { 3411 if (requires_hole_check) {
3161 if (IsFastSmiElementsKind(hinstr->elements_kind())) { 3412 if (IsFastSmiElementsKind(hinstr->elements_kind())) {
3162 Condition smi = __ CheckSmi(result); 3413 Condition smi = __ CheckSmi(result);
3163 DeoptimizeIf(NegateCondition(smi), instr->environment()); 3414 DeoptimizeIf(NegateCondition(smi), instr->environment());
3164 } else { 3415 } else {
3165 __ CompareRoot(result, Heap::kTheHoleValueRootIndex); 3416 __ CompareRoot(result, Heap::kTheHoleValueRootIndex);
3166 DeoptimizeIf(equal, instr->environment()); 3417 DeoptimizeIf(equal, instr->environment());
3167 } 3418 }
(...skipping 826 matching lines...) Expand 10 before | Expand all | Expand 10 after
3994 __ store_rax(ToExternalReference(object)); 4245 __ store_rax(ToExternalReference(object));
3995 } else { 4246 } else {
3996 Register object = ToRegister(instr->object()); 4247 Register object = ToRegister(instr->object());
3997 __ Store(MemOperand(object, offset), value, representation); 4248 __ Store(MemOperand(object, offset), value, representation);
3998 } 4249 }
3999 return; 4250 return;
4000 } 4251 }
4001 4252
4002 Register object = ToRegister(instr->object()); 4253 Register object = ToRegister(instr->object());
4003 __ AssertNotSmi(object); 4254 __ AssertNotSmi(object);
4255 #ifdef DEBUG
4256 EmitObjectAccessChecks(&access, object, true);
4257 #endif
4258
Igor Sheludko 2014/06/05 09:04:30 Extra empty line?
Jakob Kummerow 2014/06/05 14:33:31 Done.
4004 4259
4005 ASSERT(!representation.IsSmi() || 4260 ASSERT(!representation.IsSmi() ||
4006 !instr->value()->IsConstantOperand() || 4261 !instr->value()->IsConstantOperand() ||
4007 IsInteger32Constant(LConstantOperand::cast(instr->value()))); 4262 IsInteger32Constant(LConstantOperand::cast(instr->value())));
4008 if (representation.IsDouble()) { 4263 if (representation.IsDouble()) {
4009 ASSERT(access.IsInobject()); 4264 ASSERT(access.IsInobject());
4010 ASSERT(!hinstr->has_transition()); 4265 ASSERT(!hinstr->has_transition());
4011 ASSERT(!hinstr->NeedsWriteBarrier()); 4266 ASSERT(!hinstr->NeedsWriteBarrier());
4012 XMMRegister value = ToDoubleRegister(instr->value()); 4267 XMMRegister value = ToDoubleRegister(instr->value());
4013 __ movsd(FieldOperand(object, offset), value); 4268 __ movsd(FieldOperand(object, offset), value);
(...skipping 153 matching lines...) Expand 10 before | Expand all | Expand 10 after
4167 4422
4168 void LCodeGen::DoStoreKeyedExternalArray(LStoreKeyed* instr) { 4423 void LCodeGen::DoStoreKeyedExternalArray(LStoreKeyed* instr) {
4169 ElementsKind elements_kind = instr->elements_kind(); 4424 ElementsKind elements_kind = instr->elements_kind();
4170 LOperand* key = instr->key(); 4425 LOperand* key = instr->key();
4171 Operand operand(BuildFastArrayOperand( 4426 Operand operand(BuildFastArrayOperand(
4172 instr->elements(), 4427 instr->elements(),
4173 key, 4428 key,
4174 elements_kind, 4429 elements_kind,
4175 instr->base_offset())); 4430 instr->base_offset()));
4176 4431
4432 #ifdef DEBUG
4433 if (!IsExternalArrayElementsKind(elements_kind)) {
4434 EmitKeyedAccessCheck(instr->elements(), operand);
4435 }
4436 #endif
4437
4177 if (elements_kind == EXTERNAL_FLOAT32_ELEMENTS || 4438 if (elements_kind == EXTERNAL_FLOAT32_ELEMENTS ||
4178 elements_kind == FLOAT32_ELEMENTS) { 4439 elements_kind == FLOAT32_ELEMENTS) {
4179 XMMRegister value(ToDoubleRegister(instr->value())); 4440 XMMRegister value(ToDoubleRegister(instr->value()));
4180 __ cvtsd2ss(value, value); 4441 __ cvtsd2ss(value, value);
4181 __ movss(operand, value); 4442 __ movss(operand, value);
4182 } else if (elements_kind == EXTERNAL_FLOAT64_ELEMENTS || 4443 } else if (elements_kind == EXTERNAL_FLOAT64_ELEMENTS ||
4183 elements_kind == FLOAT64_ELEMENTS) { 4444 elements_kind == FLOAT64_ELEMENTS) {
4184 __ movsd(operand, ToDoubleRegister(instr->value())); 4445 __ movsd(operand, ToDoubleRegister(instr->value()));
4185 } else { 4446 } else {
4186 Register value(ToRegister(instr->value())); 4447 Register value(ToRegister(instr->value()));
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after
4238 __ movq(value, kScratchRegister); 4499 __ movq(value, kScratchRegister);
4239 4500
4240 __ bind(&have_value); 4501 __ bind(&have_value);
4241 } 4502 }
4242 4503
4243 Operand double_store_operand = BuildFastArrayOperand( 4504 Operand double_store_operand = BuildFastArrayOperand(
4244 instr->elements(), 4505 instr->elements(),
4245 key, 4506 key,
4246 FAST_DOUBLE_ELEMENTS, 4507 FAST_DOUBLE_ELEMENTS,
4247 instr->base_offset()); 4508 instr->base_offset());
4248 4509 #ifdef DEBUG
4510 EmitKeyedAccessCheck(instr->elements(), double_store_operand);
4511 #endif
4249 __ movsd(double_store_operand, value); 4512 __ movsd(double_store_operand, value);
4250 } 4513 }
4251 4514
4252 4515
4253 void LCodeGen::DoStoreKeyedFixedArray(LStoreKeyed* instr) { 4516 void LCodeGen::DoStoreKeyedFixedArray(LStoreKeyed* instr) {
4254 HStoreKeyed* hinstr = instr->hydrogen(); 4517 HStoreKeyed* hinstr = instr->hydrogen();
4255 LOperand* key = instr->key(); 4518 LOperand* key = instr->key();
4256 int offset = instr->base_offset(); 4519 int offset = instr->base_offset();
4257 Representation representation = hinstr->value()->representation(); 4520 Representation representation = hinstr->value()->representation();
4258 4521
(...skipping 14 matching lines...) Expand all
4273 STATIC_ASSERT(kSmiTag == 0); 4536 STATIC_ASSERT(kSmiTag == 0);
4274 ASSERT(kSmiTagSize + kSmiShiftSize == 32); 4537 ASSERT(kSmiTagSize + kSmiShiftSize == 32);
4275 offset += kPointerSize / 2; 4538 offset += kPointerSize / 2;
4276 } 4539 }
4277 4540
4278 Operand operand = 4541 Operand operand =
4279 BuildFastArrayOperand(instr->elements(), 4542 BuildFastArrayOperand(instr->elements(),
4280 key, 4543 key,
4281 FAST_ELEMENTS, 4544 FAST_ELEMENTS,
4282 offset); 4545 offset);
4546 #ifdef DEBUG
4547 EmitKeyedAccessCheck(instr->elements(), operand);
4548 #endif
4283 if (instr->value()->IsRegister()) { 4549 if (instr->value()->IsRegister()) {
4284 __ Store(operand, ToRegister(instr->value()), representation); 4550 __ Store(operand, ToRegister(instr->value()), representation);
4285 } else { 4551 } else {
4286 LConstantOperand* operand_value = LConstantOperand::cast(instr->value()); 4552 LConstantOperand* operand_value = LConstantOperand::cast(instr->value());
4287 if (IsInteger32Constant(operand_value)) { 4553 if (IsInteger32Constant(operand_value)) {
4288 int32_t value = ToInteger32(operand_value); 4554 int32_t value = ToInteger32(operand_value);
4289 if (representation.IsSmi()) { 4555 if (representation.IsSmi()) {
4290 __ Move(operand, Smi::FromInt(value)); 4556 __ Move(operand, Smi::FromInt(value));
4291 4557
4292 } else { 4558 } else {
(...skipping 1390 matching lines...) Expand 10 before | Expand all | Expand 10 after
5683 __ bind(deferred->exit()); 5949 __ bind(deferred->exit());
5684 __ bind(&done); 5950 __ bind(&done);
5685 } 5951 }
5686 5952
5687 5953
5688 #undef __ 5954 #undef __
5689 5955
5690 } } // namespace v8::internal 5956 } } // namespace v8::internal
5691 5957
5692 #endif // V8_TARGET_ARCH_X64 5958 #endif // V8_TARGET_ARCH_X64
OLDNEW
« src/objects.h ('K') | « src/x64/lithium-codegen-x64.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698