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

Side by Side Diff: src/builtins.cc

Issue 1617503003: [Atomics] code stubs for atomic operations (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: remove unnecessary CSA additions Created 4 years, 10 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
OLDNEW
1 // Copyright 2012 the V8 project authors. All rights reserved. 1 // Copyright 2012 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/builtins.h" 5 #include "src/builtins.h"
6 6
7 #include "src/api.h" 7 #include "src/api.h"
8 #include "src/api-natives.h" 8 #include "src/api-natives.h"
9 #include "src/arguments.h" 9 #include "src/arguments.h"
10 #include "src/base/once.h" 10 #include "src/base/once.h"
11 #include "src/bootstrapper.h" 11 #include "src/bootstrapper.h"
12 #include "src/compiler/code-stub-assembler.h"
12 #include "src/dateparser-inl.h" 13 #include "src/dateparser-inl.h"
13 #include "src/elements.h" 14 #include "src/elements.h"
14 #include "src/frames-inl.h" 15 #include "src/frames-inl.h"
15 #include "src/gdb-jit.h" 16 #include "src/gdb-jit.h"
16 #include "src/ic/handler-compiler.h" 17 #include "src/ic/handler-compiler.h"
17 #include "src/ic/ic.h" 18 #include "src/ic/ic.h"
18 #include "src/isolate-inl.h" 19 #include "src/isolate-inl.h"
19 #include "src/messages.h" 20 #include "src/messages.h"
20 #include "src/profiler/cpu-profiler.h" 21 #include "src/profiler/cpu-profiler.h"
21 #include "src/property-descriptor.h" 22 #include "src/property-descriptor.h"
(...skipping 4329 matching lines...) Expand 10 before | Expand all | Expand 10 after
4351 void Builtins::Generate_InterruptCheck(MacroAssembler* masm) { 4352 void Builtins::Generate_InterruptCheck(MacroAssembler* masm) {
4352 masm->TailCallRuntime(Runtime::kInterrupt); 4353 masm->TailCallRuntime(Runtime::kInterrupt);
4353 } 4354 }
4354 4355
4355 4356
4356 void Builtins::Generate_StackCheck(MacroAssembler* masm) { 4357 void Builtins::Generate_StackCheck(MacroAssembler* masm) {
4357 masm->TailCallRuntime(Runtime::kStackGuard); 4358 masm->TailCallRuntime(Runtime::kStackGuard);
4358 } 4359 }
4359 4360
4360 4361
4362 namespace {
4363
4364 void ValidateSharedTypedArray(compiler::CodeStubAssembler* a,
4365 compiler::Node* tagged) {
4366 using namespace compiler;
4367 CodeStubAssembler::Label is_smi(a), not_smi(a), is_typed_array(a),
4368 not_typed_array(a), is_shared(a), not_shared(a), is_float(a),
4369 not_float(a), invalid(a);
4370 Node* context = a->Context();
4371
4372 // Check if it is a heap object.
4373 a->Branch(a->WordIsSmi(tagged), &is_smi, &not_smi);
4374 a->Bind(&is_smi);
4375 a->Goto(&invalid);
binji 2016/02/12 01:46:56 This Bind/Goto dance I end up having to do a lot o
4376
4377 // Check if the array's instance type is JSTypedArray.
4378 a->Bind(&not_smi);
4379 a->Branch(a->WordEqual(a->InstanceType(tagged),
4380 a->Int32Constant(JS_TYPED_ARRAY_TYPE)),
4381 &is_typed_array, &not_typed_array);
4382 a->Bind(&not_typed_array);
4383 a->Goto(&invalid);
4384
4385 // Check if the array's JSArrayBuffer is shared.
4386 a->Bind(&is_typed_array);
4387 Node* is_buffer_shared =
4388 a->BitFieldValue<JSArrayBuffer::IsShared>(a->LoadObjectField(
4389 a->LoadObjectField(tagged, JSTypedArray::kBufferOffset),
4390 JSArrayBuffer::kBitFieldOffset));
4391 a->Branch(is_buffer_shared, &is_shared, &not_shared);
4392 a->Bind(&not_shared);
4393 a->Goto(&invalid);
4394
4395 // Check if the array's element type is float32 or float64.
4396 // TODO(binji): should fail on clamped as well.
4397 a->Bind(&is_shared);
4398 Node* elements_instance_type =
4399 a->InstanceType(a->LoadObjectField(tagged, JSObject::kElementsOffset));
4400 a->Branch(a->WordOr(a->WordEqual(elements_instance_type,
4401 a->Int32Constant(FIXED_FLOAT32_ARRAY_TYPE)),
4402 a->WordEqual(elements_instance_type,
4403 a->Int32Constant(FIXED_FLOAT64_ARRAY_TYPE))),
4404 &is_float, &not_float);
4405 a->Bind(&is_float);
4406 a->Goto(&invalid);
4407
4408 a->Bind(&invalid);
4409 a->TailCallRuntime(Runtime::kThrowNotIntegerSharedTypedArrayError, context,
4410 tagged);
4411
4412 a->Bind(&not_float);
4413 }
4414
4415
4416 compiler::Node* TaggedNumberAsWord32(compiler::CodeStubAssembler* a,
4417 compiler::Node* tagged) {
4418 using namespace compiler;
4419 CodeStubAssembler::Label is_smi(a), is_not_smi(a), is_word(a);
4420 CodeStubAssembler::Variable result(a, MachineRepresentation::kWord32);
4421
4422 a->Branch(a->WordIsSmi(tagged), &is_smi, &is_not_smi);
4423
4424 a->Bind(&is_smi);
4425 result.Bind(a->SmiUntag(tagged));
4426 a->Goto(&is_word);
4427
4428 a->Bind(&is_not_smi);
4429 result.Bind(a->ChangeFloat64ToUint32(a->LoadHeapNumber(tagged)));
4430 a->Goto(&is_word);
4431
4432 a->Bind(&is_word);
4433 return result.value();
4434 }
4435
4436
4437 compiler::Node* ConvertTaggedAtomicIndexToWord32(compiler::CodeStubAssembler* a,
4438 compiler::Node* tagged) {
4439 using namespace compiler;
4440 CodeStubAssembler::Label is_smi(a), is_not_smi(a), is_string(a),
4441 is_not_string(a), strings_equal(a), strings_not_equal(a),
4442 string_number_is_smi(a), string_number_is_not_smi(a), is_number(a),
4443 convert_number(a), is_unknown(a), is_integer(a), is_not_integer(a),
4444 is_word(a), invalid(a);
4445 CodeStubAssembler::Variable number(a, MachineRepresentation::kTagged);
4446 CodeStubAssembler::Variable word(a, MachineRepresentation::kWord32);
4447 Node* context = a->Context();
4448
4449 // Check if the index's type is a Smi.
4450 a->Branch(a->WordIsSmi(tagged), &is_smi, &is_not_smi);
4451
4452 // Check if the index's type is a String.
4453 a->Bind(&is_not_smi);
4454 Node* instance_type = a->InstanceType(tagged);
4455 a->Branch(a->WordEqual(
4456 a->WordAnd(instance_type, a->Int32Constant(kIsNotStringMask)),
4457 a->Int32Constant(0)),
4458 &is_string, &is_not_string);
4459
4460 // Check that converting the string to a number and back is equal to itself.
4461 a->Bind(&is_string);
4462 Node* string_as_number =
4463 a->CallRuntime(Runtime::kStringToNumber, context, tagged);
4464 a->Branch(
4465 a->WordEqual(a->CallRuntime(Runtime::kStringEquals, context,
4466 a->CallRuntime(Runtime::kNumberToString,
4467 context, string_as_number),
4468 tagged),
4469 a->Int32Constant(EQUAL)),
4470 &strings_equal, &strings_not_equal);
4471
4472 a->Bind(&strings_not_equal);
4473 a->Goto(&invalid);
4474
4475 // Check if the string converted to a number is a Smi.
4476 a->Bind(&strings_equal);
4477 a->Branch(a->WordIsSmi(string_as_number), &string_number_is_smi,
4478 &string_number_is_not_smi);
4479
4480 // If the string-number is a Smi, untag it.
4481 a->Bind(&string_number_is_smi);
4482 word.Bind(a->SmiUntag(string_as_number));
4483 a->Goto(&is_word);
4484
4485 // If the string-number is a HeapNumber, convert it to a word32.
4486 a->Bind(&string_number_is_not_smi);
4487 number.Bind(string_as_number);
4488 a->Goto(&convert_number);
4489
4490 // Check if the index's type is a HeapNumber.
4491 a->Bind(&is_not_string);
4492 a->Branch(a->WordEqual(instance_type, a->Int32Constant(HEAP_NUMBER_TYPE)),
4493 &is_number, &is_unknown);
4494
4495 // Index is an invalid type, throw.
4496 a->Bind(&is_unknown);
4497 a->Goto(&invalid);
4498
4499 a->Bind(&is_number);
4500 number.Bind(tagged);
4501 a->Goto(&convert_number);
4502
4503 // Convert index from a HeapNumber to a word32.
4504 a->Bind(&convert_number);
4505 Node* number_value = a->LoadHeapNumber(number.value());
4506 word.Bind(a->ChangeFloat64ToUint32(number_value));
4507
4508 // Check that the index is an integer.
4509 a->Branch(
4510 a->Float64Equal(a->ChangeUint32ToFloat64(word.value()), number_value),
4511 &is_integer, &is_not_integer);
4512
4513 a->Bind(&is_not_integer);
4514 a->Goto(&invalid);
4515
4516 a->Bind(&is_integer);
4517 a->Goto(&is_word);
4518
4519 // Index is a Smi, untag.
4520 a->Bind(&is_smi);
4521 word.Bind(a->SmiUntag(tagged));
4522 a->Goto(&is_word);
4523
4524 a->Bind(&invalid);
4525 a->TailCallRuntime(Runtime::kThrowInvalidAtomicAccessIndexError, context);
4526
4527 a->Bind(&is_word);
4528 return word.value();
4529 }
4530
4531
4532 void ValidateAtomicIndex(compiler::CodeStubAssembler* a,
4533 compiler::Node* index_word,
4534 compiler::Node* array_length_word) {
4535 using namespace compiler;
4536 // Check if the index is in bounds. If not, throw RangeError.
4537 CodeStubAssembler::Label in_bounds(a), not_in_bounds(a);
4538 a->Branch(
4539 a->WordOr(a->Int32LessThan(index_word, a->Int32Constant(0)),
4540 a->Int32GreaterThanOrEqual(index_word, array_length_word)),
4541 &not_in_bounds, &in_bounds);
4542 a->Bind(&not_in_bounds);
4543 a->TailCallRuntime(Runtime::kThrowInvalidAtomicAccessIndexError,
4544 a->Context());
4545 a->Bind(&in_bounds);
4546 }
4547
4548 } // anonymous namespace
4549
4550
4551 void Builtins::Generate_AtomicsLoadCheck(MacroAssembler* masm) {
4552 using namespace compiler;
4553 Isolate* isolate = masm->isolate();
4554 Zone zone;
4555 CodeStubAssembler a(isolate, &zone, 2, Code::ComputeFlags(Code::STUB),
4556 "AtomicsLoadCheck");
4557
4558 Node* array = a.Parameter(0);
4559 Node* index = a.Parameter(1);
4560 ValidateSharedTypedArray(&a, array);
4561 Node* index_word = ConvertTaggedAtomicIndexToWord32(&a, index);
4562 Node* array_length_word = TaggedNumberAsWord32(
4563 &a, a.LoadObjectField(array, JSTypedArray::kLengthOffset));
4564 ValidateAtomicIndex(&a, index_word, array_length_word);
4565
4566 AtomicsLoadStub stub(isolate);
4567 // TODO(binji): can't just re-tag index, because it might be out of range.
4568 // Can we just pass the untagged index value to the code stub?
4569 Node* stub_args[] = {array, a.SmiTag(index_word), a.Context()};
4570 a.TailCallStub(stub, stub_args);
4571
4572 masm->Jump(a.GenerateCode(), RelocInfo::CODE_TARGET);
binji 2016/02/12 01:46:56 Is this right? I've seen some errors when I run ce
4573 }
4574
4575
4361 #define DEFINE_BUILTIN_ACCESSOR_C(name, ignore) \ 4576 #define DEFINE_BUILTIN_ACCESSOR_C(name, ignore) \
4362 Handle<Code> Builtins::name() { \ 4577 Handle<Code> Builtins::name() { \
4363 Code** code_address = \ 4578 Code** code_address = \
4364 reinterpret_cast<Code**>(builtin_address(k##name)); \ 4579 reinterpret_cast<Code**>(builtin_address(k##name)); \
4365 return Handle<Code>(code_address); \ 4580 return Handle<Code>(code_address); \
4366 } 4581 }
4367 #define DEFINE_BUILTIN_ACCESSOR_A(name, kind, state, extra) \ 4582 #define DEFINE_BUILTIN_ACCESSOR_A(name, kind, state, extra) \
4368 Handle<Code> Builtins::name() { \ 4583 Handle<Code> Builtins::name() { \
4369 Code** code_address = \ 4584 Code** code_address = \
4370 reinterpret_cast<Code**>(builtin_address(k##name)); \ 4585 reinterpret_cast<Code**>(builtin_address(k##name)); \
4371 return Handle<Code>(code_address); \ 4586 return Handle<Code>(code_address); \
4372 } 4587 }
4373 #define DEFINE_BUILTIN_ACCESSOR_H(name, kind) \ 4588 #define DEFINE_BUILTIN_ACCESSOR_H(name, kind) \
4374 Handle<Code> Builtins::name() { \ 4589 Handle<Code> Builtins::name() { \
4375 Code** code_address = \ 4590 Code** code_address = \
4376 reinterpret_cast<Code**>(builtin_address(k##name)); \ 4591 reinterpret_cast<Code**>(builtin_address(k##name)); \
4377 return Handle<Code>(code_address); \ 4592 return Handle<Code>(code_address); \
4378 } 4593 }
4379 BUILTIN_LIST_C(DEFINE_BUILTIN_ACCESSOR_C) 4594 BUILTIN_LIST_C(DEFINE_BUILTIN_ACCESSOR_C)
4380 BUILTIN_LIST_A(DEFINE_BUILTIN_ACCESSOR_A) 4595 BUILTIN_LIST_A(DEFINE_BUILTIN_ACCESSOR_A)
4381 BUILTIN_LIST_H(DEFINE_BUILTIN_ACCESSOR_H) 4596 BUILTIN_LIST_H(DEFINE_BUILTIN_ACCESSOR_H)
4382 BUILTIN_LIST_DEBUG_A(DEFINE_BUILTIN_ACCESSOR_A) 4597 BUILTIN_LIST_DEBUG_A(DEFINE_BUILTIN_ACCESSOR_A)
4383 #undef DEFINE_BUILTIN_ACCESSOR_C 4598 #undef DEFINE_BUILTIN_ACCESSOR_C
4384 #undef DEFINE_BUILTIN_ACCESSOR_A 4599 #undef DEFINE_BUILTIN_ACCESSOR_A
4385 4600
4386 4601
4387 } // namespace internal 4602 } // namespace internal
4388 } // namespace v8 4603 } // namespace v8
OLDNEW
« no previous file with comments | « src/builtins.h ('k') | src/code-factory.h » ('j') | src/compiler/code-stub-assembler.cc » ('J')

Powered by Google App Engine
This is Rietveld 408576698