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

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 Context() 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
« no previous file with comments | « src/builtins.h ('k') | src/code-factory.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 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, compiler::Node* context) {
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
4371 // Check if it is a heap object.
4372 a->Branch(a->WordIsSmi(tagged), &is_smi, &not_smi);
4373 a->Bind(&is_smi);
4374 a->Goto(&invalid);
4375
4376 // Check if the array's instance type is JSTypedArray.
4377 a->Bind(&not_smi);
4378 a->Branch(a->WordEqual(a->InstanceType(tagged),
4379 a->Int32Constant(JS_TYPED_ARRAY_TYPE)),
4380 &is_typed_array, &not_typed_array);
4381 a->Bind(&not_typed_array);
4382 a->Goto(&invalid);
4383
4384 // Check if the array's JSArrayBuffer is shared.
4385 a->Bind(&is_typed_array);
4386 Node* is_buffer_shared =
4387 a->BitFieldValue<JSArrayBuffer::IsShared>(a->LoadObjectField(
4388 a->LoadObjectField(tagged, JSTypedArray::kBufferOffset),
4389 JSArrayBuffer::kBitFieldOffset));
4390 a->Branch(is_buffer_shared, &is_shared, &not_shared);
4391 a->Bind(&not_shared);
4392 a->Goto(&invalid);
4393
4394 // Check if the array's element type is float32 or float64.
4395 // TODO(binji): should fail on clamped as well.
4396 a->Bind(&is_shared);
4397 Node* elements_instance_type =
4398 a->InstanceType(a->LoadObjectField(tagged, JSObject::kElementsOffset));
4399 a->Branch(a->WordOr(a->WordEqual(elements_instance_type,
4400 a->Int32Constant(FIXED_FLOAT32_ARRAY_TYPE)),
4401 a->WordEqual(elements_instance_type,
4402 a->Int32Constant(FIXED_FLOAT64_ARRAY_TYPE))),
4403 &is_float, &not_float);
4404 a->Bind(&is_float);
4405 a->Goto(&invalid);
4406
4407 a->Bind(&invalid);
4408 a->TailCallRuntime(Runtime::kThrowNotIntegerSharedTypedArrayError, context,
4409 tagged);
4410
4411 a->Bind(&not_float);
4412 }
4413
4414
4415 compiler::Node* TaggedNumberAsWord32(compiler::CodeStubAssembler* a,
4416 compiler::Node* tagged) {
4417 using namespace compiler;
4418 CodeStubAssembler::Label is_smi(a), is_not_smi(a), is_word(a);
4419 CodeStubAssembler::Variable result(a, MachineRepresentation::kWord32);
4420
4421 a->Branch(a->WordIsSmi(tagged), &is_smi, &is_not_smi);
4422
4423 a->Bind(&is_smi);
4424 result.Bind(a->SmiUntag(tagged));
4425 a->Goto(&is_word);
4426
4427 a->Bind(&is_not_smi);
4428 result.Bind(a->ChangeFloat64ToUint32(a->LoadHeapNumber(tagged)));
4429 a->Goto(&is_word);
4430
4431 a->Bind(&is_word);
4432 return result.value();
4433 }
4434
4435
4436 compiler::Node* ConvertTaggedAtomicIndexToWord32(compiler::CodeStubAssembler* a,
4437 compiler::Node* tagged,
4438 compiler::Node* context) {
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
4448 // Check if the index's type is a Smi.
4449 a->Branch(a->WordIsSmi(tagged), &is_smi, &is_not_smi);
4450
4451 // Check if the index's type is a String.
4452 a->Bind(&is_not_smi);
4453 Node* instance_type = a->InstanceType(tagged);
4454 a->Branch(a->WordEqual(
4455 a->WordAnd(instance_type, a->Int32Constant(kIsNotStringMask)),
4456 a->Int32Constant(0)),
4457 &is_string, &is_not_string);
4458
4459 // Check that converting the string to a number and back is equal to itself.
4460 a->Bind(&is_string);
4461 Node* string_as_number =
4462 a->CallRuntime(Runtime::kStringToNumber, context, tagged);
4463 a->Branch(
4464 a->WordEqual(a->CallRuntime(Runtime::kStringEquals, context,
4465 a->CallRuntime(Runtime::kNumberToString,
4466 context, string_as_number),
4467 tagged),
4468 a->Int32Constant(EQUAL)),
4469 &strings_equal, &strings_not_equal);
4470
4471 a->Bind(&strings_not_equal);
4472 a->Goto(&invalid);
4473
4474 // Check if the string converted to a number is a Smi.
4475 a->Bind(&strings_equal);
4476 a->Branch(a->WordIsSmi(string_as_number), &string_number_is_smi,
4477 &string_number_is_not_smi);
4478
4479 // If the string-number is a Smi, untag it.
4480 a->Bind(&string_number_is_smi);
4481 word.Bind(a->SmiUntag(string_as_number));
4482 a->Goto(&is_word);
4483
4484 // If the string-number is a HeapNumber, convert it to a word32.
4485 a->Bind(&string_number_is_not_smi);
4486 number.Bind(string_as_number);
4487 a->Goto(&convert_number);
4488
4489 // Check if the index's type is a HeapNumber.
4490 a->Bind(&is_not_string);
4491 a->Branch(a->WordEqual(instance_type, a->Int32Constant(HEAP_NUMBER_TYPE)),
4492 &is_number, &is_unknown);
4493
4494 // Index is an invalid type, throw.
4495 a->Bind(&is_unknown);
4496 a->Goto(&invalid);
4497
4498 a->Bind(&is_number);
4499 number.Bind(tagged);
4500 a->Goto(&convert_number);
4501
4502 // Convert index from a HeapNumber to a word32.
4503 a->Bind(&convert_number);
4504 Node* number_value = a->LoadHeapNumber(number.value());
4505 word.Bind(a->ChangeFloat64ToUint32(number_value));
4506
4507 // Check that the index is an integer.
4508 a->Branch(
4509 a->Float64Equal(a->ChangeUint32ToFloat64(word.value()), number_value),
4510 &is_integer, &is_not_integer);
4511
4512 a->Bind(&is_not_integer);
4513 a->Goto(&invalid);
4514
4515 a->Bind(&is_integer);
4516 a->Goto(&is_word);
4517
4518 // Index is a Smi, untag.
4519 a->Bind(&is_smi);
4520 word.Bind(a->SmiUntag(tagged));
4521 a->Goto(&is_word);
4522
4523 a->Bind(&invalid);
4524 a->TailCallRuntime(Runtime::kThrowInvalidAtomicAccessIndexError, context);
4525
4526 a->Bind(&is_word);
4527 return word.value();
4528 }
4529
4530
4531 void ValidateAtomicIndex(compiler::CodeStubAssembler* a,
4532 compiler::Node* index_word,
4533 compiler::Node* array_length_word,
4534 compiler::Node* context) {
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 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 Node* context = a.Parameter(2);
Jarin 2016/02/15 10:30:15 I am a bit surprised that the parameters work here
binji 2016/02/15 20:31:31 Yes, you're right! Thanks, that was the bug I was
4561 ValidateSharedTypedArray(&a, array, context);
4562 Node* index_word = ConvertTaggedAtomicIndexToWord32(&a, index, context);
4563 Node* array_length_word = TaggedNumberAsWord32(
4564 &a, a.LoadObjectField(array, JSTypedArray::kLengthOffset));
4565 ValidateAtomicIndex(&a, index_word, array_length_word, context);
4566
4567 AtomicsLoadStub stub(isolate);
4568 // TODO(binji): can't just re-tag index, because it might be out of range.
4569 // Can we just pass the untagged index value to the code stub?
4570 Node* stub_args[] = {array, a.SmiTag(index_word), context};
4571 a.TailCallStub(stub, stub_args);
4572
4573 masm->Jump(a.GenerateCode(), RelocInfo::CODE_TARGET);
4574 }
4575
4576
4361 #define DEFINE_BUILTIN_ACCESSOR_C(name, ignore) \ 4577 #define DEFINE_BUILTIN_ACCESSOR_C(name, ignore) \
4362 Handle<Code> Builtins::name() { \ 4578 Handle<Code> Builtins::name() { \
4363 Code** code_address = \ 4579 Code** code_address = \
4364 reinterpret_cast<Code**>(builtin_address(k##name)); \ 4580 reinterpret_cast<Code**>(builtin_address(k##name)); \
4365 return Handle<Code>(code_address); \ 4581 return Handle<Code>(code_address); \
4366 } 4582 }
4367 #define DEFINE_BUILTIN_ACCESSOR_A(name, kind, state, extra) \ 4583 #define DEFINE_BUILTIN_ACCESSOR_A(name, kind, state, extra) \
4368 Handle<Code> Builtins::name() { \ 4584 Handle<Code> Builtins::name() { \
4369 Code** code_address = \ 4585 Code** code_address = \
4370 reinterpret_cast<Code**>(builtin_address(k##name)); \ 4586 reinterpret_cast<Code**>(builtin_address(k##name)); \
4371 return Handle<Code>(code_address); \ 4587 return Handle<Code>(code_address); \
4372 } 4588 }
4373 #define DEFINE_BUILTIN_ACCESSOR_H(name, kind) \ 4589 #define DEFINE_BUILTIN_ACCESSOR_H(name, kind) \
4374 Handle<Code> Builtins::name() { \ 4590 Handle<Code> Builtins::name() { \
4375 Code** code_address = \ 4591 Code** code_address = \
4376 reinterpret_cast<Code**>(builtin_address(k##name)); \ 4592 reinterpret_cast<Code**>(builtin_address(k##name)); \
4377 return Handle<Code>(code_address); \ 4593 return Handle<Code>(code_address); \
4378 } 4594 }
4379 BUILTIN_LIST_C(DEFINE_BUILTIN_ACCESSOR_C) 4595 BUILTIN_LIST_C(DEFINE_BUILTIN_ACCESSOR_C)
4380 BUILTIN_LIST_A(DEFINE_BUILTIN_ACCESSOR_A) 4596 BUILTIN_LIST_A(DEFINE_BUILTIN_ACCESSOR_A)
4381 BUILTIN_LIST_H(DEFINE_BUILTIN_ACCESSOR_H) 4597 BUILTIN_LIST_H(DEFINE_BUILTIN_ACCESSOR_H)
4382 BUILTIN_LIST_DEBUG_A(DEFINE_BUILTIN_ACCESSOR_A) 4598 BUILTIN_LIST_DEBUG_A(DEFINE_BUILTIN_ACCESSOR_A)
4383 #undef DEFINE_BUILTIN_ACCESSOR_C 4599 #undef DEFINE_BUILTIN_ACCESSOR_C
4384 #undef DEFINE_BUILTIN_ACCESSOR_A 4600 #undef DEFINE_BUILTIN_ACCESSOR_A
4385 4601
4386 4602
4387 } // namespace internal 4603 } // namespace internal
4388 } // namespace v8 4604 } // namespace v8
OLDNEW
« no previous file with comments | « src/builtins.h ('k') | src/code-factory.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698