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

Side by Side Diff: src/code-stub-assembler.cc

Issue 2564323003: Merged: [ic] Prevent KeyedStoreIC from being generic when storing doubles to integer typed arrays. (Closed)
Patch Set: Created 4 years 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 | « src/code-stub-assembler.h ('k') | src/compiler/code-assembler.h » ('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 2016 the V8 project authors. All rights reserved. 1 // Copyright 2016 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/code-stub-assembler.h" 5 #include "src/code-stub-assembler.h"
6 #include "src/code-factory.h" 6 #include "src/code-factory.h"
7 #include "src/frames-inl.h" 7 #include "src/frames-inl.h"
8 #include "src/frames.h" 8 #include "src/frames.h"
9 #include "src/ic/handler-configuration.h" 9 #include "src/ic/handler-configuration.h"
10 #include "src/ic/stub-cache.h" 10 #include "src/ic/stub-cache.h"
(...skipping 180 matching lines...) Expand 10 before | Expand all | Expand 10 after
191 } 191 }
192 192
193 Bind(&return_minus_x); 193 Bind(&return_minus_x);
194 var_x.Bind(Float64Neg(var_x.value())); 194 var_x.Bind(Float64Neg(var_x.value()));
195 Goto(&return_x); 195 Goto(&return_x);
196 196
197 Bind(&return_x); 197 Bind(&return_x);
198 return var_x.value(); 198 return var_x.value();
199 } 199 }
200 200
201 Node* CodeStubAssembler::Float64RoundToEven(Node* x) {
202 if (IsFloat64RoundTiesEvenSupported()) {
203 return Float64RoundTiesEven(x);
204 }
205 // See ES#sec-touint8clamp for details.
206 Node* f = Float64Floor(x);
207 Node* f_and_half = Float64Add(f, Float64Constant(0.5));
208
209 Variable var_result(this, MachineRepresentation::kFloat64);
210 Label return_f(this), return_f_plus_one(this), done(this);
211
212 GotoIf(Float64LessThan(f_and_half, x), &return_f_plus_one);
213 GotoIf(Float64LessThan(x, f_and_half), &return_f);
214 {
215 Node* f_mod_2 = Float64Mod(f, Float64Constant(2.0));
216 Branch(Float64Equal(f_mod_2, Float64Constant(0.0)), &return_f,
217 &return_f_plus_one);
218 }
219
220 Bind(&return_f);
221 var_result.Bind(f);
222 Goto(&done);
223
224 Bind(&return_f_plus_one);
225 var_result.Bind(Float64Add(f, Float64Constant(1.0)));
226 Goto(&done);
227
228 Bind(&done);
229 return var_result.value();
230 }
231
201 Node* CodeStubAssembler::Float64Trunc(Node* x) { 232 Node* CodeStubAssembler::Float64Trunc(Node* x) {
202 if (IsFloat64RoundTruncateSupported()) { 233 if (IsFloat64RoundTruncateSupported()) {
203 return Float64RoundTruncate(x); 234 return Float64RoundTruncate(x);
204 } 235 }
205 236
206 Node* one = Float64Constant(1.0); 237 Node* one = Float64Constant(1.0);
207 Node* zero = Float64Constant(0.0); 238 Node* zero = Float64Constant(0.0);
208 Node* two_52 = Float64Constant(4503599627370496.0E0); 239 Node* two_52 = Float64Constant(4503599627370496.0E0);
209 Node* minus_two_52 = Float64Constant(-4503599627370496.0E0); 240 Node* minus_two_52 = Float64Constant(-4503599627370496.0E0);
210 241
(...skipping 5076 matching lines...) Expand 10 before | Expand all | Expand 10 after
5287 Node* native_context = LoadNativeContext(context); 5318 Node* native_context = LoadNativeContext(context);
5288 Node* script_context_table = 5319 Node* script_context_table =
5289 LoadContextElement(native_context, Context::SCRIPT_CONTEXT_TABLE_INDEX); 5320 LoadContextElement(native_context, Context::SCRIPT_CONTEXT_TABLE_INDEX);
5290 5321
5291 int offset = 5322 int offset =
5292 ScriptContextTable::GetContextOffset(context_index) - kHeapObjectTag; 5323 ScriptContextTable::GetContextOffset(context_index) - kHeapObjectTag;
5293 return Load(MachineType::AnyTagged(), script_context_table, 5324 return Load(MachineType::AnyTagged(), script_context_table,
5294 IntPtrConstant(offset)); 5325 IntPtrConstant(offset));
5295 } 5326 }
5296 5327
5297 Node* CodeStubAssembler::ClampedToUint8(Node* int32_value) {
5298 Label done(this);
5299 Node* int32_zero = Int32Constant(0);
5300 Node* int32_255 = Int32Constant(255);
5301 Variable var_value(this, MachineRepresentation::kWord32);
5302 var_value.Bind(int32_value);
5303 GotoIf(Uint32LessThanOrEqual(int32_value, int32_255), &done);
5304 var_value.Bind(int32_zero);
5305 GotoIf(Int32LessThan(int32_value, int32_zero), &done);
5306 var_value.Bind(int32_255);
5307 Goto(&done);
5308 Bind(&done);
5309 return var_value.value();
5310 }
5311
5312 namespace { 5328 namespace {
5313 5329
5314 // Converts typed array elements kind to a machine representations. 5330 // Converts typed array elements kind to a machine representations.
5315 MachineRepresentation ElementsKindToMachineRepresentation(ElementsKind kind) { 5331 MachineRepresentation ElementsKindToMachineRepresentation(ElementsKind kind) {
5316 switch (kind) { 5332 switch (kind) {
5317 case UINT8_CLAMPED_ELEMENTS: 5333 case UINT8_CLAMPED_ELEMENTS:
5318 case UINT8_ELEMENTS: 5334 case UINT8_ELEMENTS:
5319 case INT8_ELEMENTS: 5335 case INT8_ELEMENTS:
5320 return MachineRepresentation::kWord8; 5336 return MachineRepresentation::kWord8;
5321 case UINT16_ELEMENTS: 5337 case UINT16_ELEMENTS:
(...skipping 12 matching lines...) Expand all
5334 } 5350 }
5335 } 5351 }
5336 5352
5337 } // namespace 5353 } // namespace
5338 5354
5339 void CodeStubAssembler::StoreElement(Node* elements, ElementsKind kind, 5355 void CodeStubAssembler::StoreElement(Node* elements, ElementsKind kind,
5340 Node* index, Node* value, 5356 Node* index, Node* value,
5341 ParameterMode mode) { 5357 ParameterMode mode) {
5342 if (IsFixedTypedArrayElementsKind(kind)) { 5358 if (IsFixedTypedArrayElementsKind(kind)) {
5343 if (kind == UINT8_CLAMPED_ELEMENTS) { 5359 if (kind == UINT8_CLAMPED_ELEMENTS) {
5344 value = ClampedToUint8(value); 5360 #ifdef DEBUG
5361 Assert(Word32Equal(value, Word32And(Int32Constant(0xff), value)));
5362 #endif
5345 } 5363 }
5346 Node* offset = ElementOffsetFromIndex(index, kind, mode, 0); 5364 Node* offset = ElementOffsetFromIndex(index, kind, mode, 0);
5347 MachineRepresentation rep = ElementsKindToMachineRepresentation(kind); 5365 MachineRepresentation rep = ElementsKindToMachineRepresentation(kind);
5348 StoreNoWriteBarrier(rep, elements, offset, value); 5366 StoreNoWriteBarrier(rep, elements, offset, value);
5349 return; 5367 return;
5350 } 5368 }
5351 5369
5352 WriteBarrierMode barrier_mode = 5370 WriteBarrierMode barrier_mode =
5353 IsFastSmiElementsKind(kind) ? SKIP_WRITE_BARRIER : UPDATE_WRITE_BARRIER; 5371 IsFastSmiElementsKind(kind) ? SKIP_WRITE_BARRIER : UPDATE_WRITE_BARRIER;
5354 if (IsFastDoubleElementsKind(kind)) { 5372 if (IsFastDoubleElementsKind(kind)) {
5355 // Make sure we do not store signalling NaNs into double arrays. 5373 // Make sure we do not store signalling NaNs into double arrays.
5356 value = Float64SilenceNaN(value); 5374 value = Float64SilenceNaN(value);
5357 StoreFixedDoubleArrayElement(elements, index, value, mode); 5375 StoreFixedDoubleArrayElement(elements, index, value, mode);
5358 } else { 5376 } else {
5359 StoreFixedArrayElement(elements, index, value, barrier_mode, mode); 5377 StoreFixedArrayElement(elements, index, value, barrier_mode, mode);
5360 } 5378 }
5361 } 5379 }
5362 5380
5381 Node* CodeStubAssembler::Int32ToUint8Clamped(Node* int32_value) {
5382 Label done(this);
5383 Node* int32_zero = Int32Constant(0);
5384 Node* int32_255 = Int32Constant(255);
5385 Variable var_value(this, MachineRepresentation::kWord32);
5386 var_value.Bind(int32_value);
5387 GotoIf(Uint32LessThanOrEqual(int32_value, int32_255), &done);
5388 var_value.Bind(int32_zero);
5389 GotoIf(Int32LessThan(int32_value, int32_zero), &done);
5390 var_value.Bind(int32_255);
5391 Goto(&done);
5392 Bind(&done);
5393 return var_value.value();
5394 }
5395
5396 Node* CodeStubAssembler::Float64ToUint8Clamped(Node* float64_value) {
5397 Label done(this);
5398 Variable var_value(this, MachineRepresentation::kWord32);
5399 var_value.Bind(Int32Constant(0));
5400 GotoIf(Float64LessThanOrEqual(float64_value, Float64Constant(0.0)), &done);
5401 var_value.Bind(Int32Constant(255));
5402 GotoIf(Float64LessThanOrEqual(Float64Constant(255.0), float64_value), &done);
5403 {
5404 Node* rounded_value = Float64RoundToEven(float64_value);
5405 var_value.Bind(TruncateFloat64ToWord32(rounded_value));
5406 Goto(&done);
5407 }
5408 Bind(&done);
5409 return var_value.value();
5410 }
5411
5412 Node* CodeStubAssembler::PrepareValueForWriteToTypedArray(
5413 Node* input, ElementsKind elements_kind, Label* bailout) {
5414 DCHECK(IsFixedTypedArrayElementsKind(elements_kind));
5415
5416 MachineRepresentation rep;
5417 switch (elements_kind) {
5418 case UINT8_ELEMENTS:
5419 case INT8_ELEMENTS:
5420 case UINT16_ELEMENTS:
5421 case INT16_ELEMENTS:
5422 case UINT32_ELEMENTS:
5423 case INT32_ELEMENTS:
5424 case UINT8_CLAMPED_ELEMENTS:
5425 rep = MachineRepresentation::kWord32;
5426 break;
5427 case FLOAT32_ELEMENTS:
5428 rep = MachineRepresentation::kFloat32;
5429 break;
5430 case FLOAT64_ELEMENTS:
5431 rep = MachineRepresentation::kFloat64;
5432 break;
5433 default:
5434 UNREACHABLE();
5435 return nullptr;
5436 }
5437
5438 Variable var_result(this, rep);
5439 Label done(this, &var_result), if_smi(this);
5440 GotoIf(WordIsSmi(input), &if_smi);
5441 // Try to convert a heap number to a Smi.
5442 GotoUnless(IsHeapNumberMap(LoadMap(input)), bailout);
5443 {
5444 Node* value = LoadHeapNumberValue(input);
5445 if (rep == MachineRepresentation::kWord32) {
5446 if (elements_kind == UINT8_CLAMPED_ELEMENTS) {
5447 value = Float64ToUint8Clamped(value);
5448 } else {
5449 value = TruncateFloat64ToWord32(value);
5450 }
5451 } else if (rep == MachineRepresentation::kFloat32) {
5452 value = TruncateFloat64ToFloat32(value);
5453 } else {
5454 DCHECK_EQ(MachineRepresentation::kFloat64, rep);
5455 }
5456 var_result.Bind(value);
5457 Goto(&done);
5458 }
5459
5460 Bind(&if_smi);
5461 {
5462 Node* value = SmiToWord32(input);
5463 if (rep == MachineRepresentation::kFloat32) {
5464 value = RoundInt32ToFloat32(value);
5465 } else if (rep == MachineRepresentation::kFloat64) {
5466 value = ChangeInt32ToFloat64(value);
5467 } else {
5468 DCHECK_EQ(MachineRepresentation::kWord32, rep);
5469 if (elements_kind == UINT8_CLAMPED_ELEMENTS) {
5470 value = Int32ToUint8Clamped(value);
5471 }
5472 }
5473 var_result.Bind(value);
5474 Goto(&done);
5475 }
5476
5477 Bind(&done);
5478 return var_result.value();
5479 }
5480
5363 void CodeStubAssembler::EmitElementStore(Node* object, Node* key, Node* value, 5481 void CodeStubAssembler::EmitElementStore(Node* object, Node* key, Node* value,
5364 bool is_jsarray, 5482 bool is_jsarray,
5365 ElementsKind elements_kind, 5483 ElementsKind elements_kind,
5366 KeyedAccessStoreMode store_mode, 5484 KeyedAccessStoreMode store_mode,
5367 Label* bailout) { 5485 Label* bailout) {
5368 Node* elements = LoadElements(object); 5486 Node* elements = LoadElements(object);
5369 if (IsFastSmiOrObjectElementsKind(elements_kind) && 5487 if (IsFastSmiOrObjectElementsKind(elements_kind) &&
5370 store_mode != STORE_NO_TRANSITION_HANDLE_COW) { 5488 store_mode != STORE_NO_TRANSITION_HANDLE_COW) {
5371 // Bailout in case of COW elements. 5489 // Bailout in case of COW elements.
5372 GotoIf(WordNotEqual(LoadMap(elements), 5490 GotoIf(WordNotEqual(LoadMap(elements),
5373 LoadRoot(Heap::kFixedArrayMapRootIndex)), 5491 LoadRoot(Heap::kFixedArrayMapRootIndex)),
5374 bailout); 5492 bailout);
5375 } 5493 }
5376 // TODO(ishell): introduce TryToIntPtrOrSmi() and use OptimalParameterMode(). 5494 // TODO(ishell): introduce TryToIntPtrOrSmi() and use OptimalParameterMode().
5377 ParameterMode parameter_mode = INTPTR_PARAMETERS; 5495 ParameterMode parameter_mode = INTPTR_PARAMETERS;
5378 key = TryToIntptr(key, bailout); 5496 key = TryToIntptr(key, bailout);
5379 5497
5380 if (IsFixedTypedArrayElementsKind(elements_kind)) { 5498 if (IsFixedTypedArrayElementsKind(elements_kind)) {
5381 Label done(this); 5499 Label done(this);
5382 // TODO(ishell): call ToNumber() on value and don't bailout but be careful 5500 // TODO(ishell): call ToNumber() on value and don't bailout but be careful
5383 // to call it only once if we decide to bailout because of bounds checks. 5501 // to call it only once if we decide to bailout because of bounds checks.
5384 5502
5385 if (IsFixedFloatElementsKind(elements_kind)) { 5503 value = PrepareValueForWriteToTypedArray(value, elements_kind, bailout);
5386 // TODO(ishell): move float32 truncation into PrepareValueForWrite.
5387 value = PrepareValueForWrite(value, Representation::Double(), bailout);
5388 if (elements_kind == FLOAT32_ELEMENTS) {
5389 value = TruncateFloat64ToFloat32(value);
5390 }
5391 } else {
5392 // TODO(ishell): It's fine for word8/16/32 to truncate the result.
5393 value = TryToIntptr(value, bailout);
5394 }
5395 5504
5396 // There must be no allocations between the buffer load and 5505 // There must be no allocations between the buffer load and
5397 // and the actual store to backing store, because GC may decide that 5506 // and the actual store to backing store, because GC may decide that
5398 // the buffer is not alive or move the elements. 5507 // the buffer is not alive or move the elements.
5399 // TODO(ishell): introduce DisallowHeapAllocationCode scope here. 5508 // TODO(ishell): introduce DisallowHeapAllocationCode scope here.
5400 5509
5401 // Check if buffer has been neutered. 5510 // Check if buffer has been neutered.
5402 Node* buffer = LoadObjectField(object, JSArrayBufferView::kBufferOffset); 5511 Node* buffer = LoadObjectField(object, JSArrayBufferView::kBufferOffset);
5403 Node* bitfield = LoadObjectField(buffer, JSArrayBuffer::kBitFieldOffset, 5512 Node* bitfield = LoadObjectField(buffer, JSArrayBuffer::kBitFieldOffset,
5404 MachineType::Uint32()); 5513 MachineType::Uint32());
(...skipping 358 matching lines...) Expand 10 before | Expand all | Expand 10 after
5763 Heap::kTheHoleValueRootIndex); 5872 Heap::kTheHoleValueRootIndex);
5764 5873
5765 // Store the WeakCell in the feedback vector. 5874 // Store the WeakCell in the feedback vector.
5766 StoreFixedArrayElement(feedback_vector, slot, cell, UPDATE_WRITE_BARRIER, 5875 StoreFixedArrayElement(feedback_vector, slot, cell, UPDATE_WRITE_BARRIER,
5767 CodeStubAssembler::SMI_PARAMETERS); 5876 CodeStubAssembler::SMI_PARAMETERS);
5768 return cell; 5877 return cell;
5769 } 5878 }
5770 5879
5771 } // namespace internal 5880 } // namespace internal
5772 } // namespace v8 5881 } // namespace v8
OLDNEW
« no previous file with comments | « src/code-stub-assembler.h ('k') | src/compiler/code-assembler.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698