OLD | NEW |
1 // Copyright 2013 the V8 project authors. All rights reserved. | 1 // Copyright 2013 the V8 project authors. All rights reserved. |
2 // Redistribution and use in source and binary forms, with or without | 2 // Redistribution and use in source and binary forms, with or without |
3 // modification, are permitted provided that the following conditions are | 3 // modification, are permitted provided that the following conditions are |
4 // met: | 4 // met: |
5 // | 5 // |
6 // * Redistributions of source code must retain the above copyright | 6 // * Redistributions of source code must retain the above copyright |
7 // notice, this list of conditions and the following disclaimer. | 7 // notice, this list of conditions and the following disclaimer. |
8 // * Redistributions in binary form must reproduce the above | 8 // * Redistributions in binary form must reproduce the above |
9 // copyright notice, this list of conditions and the following | 9 // copyright notice, this list of conditions and the following |
10 // disclaimer in the documentation and/or other materials provided | 10 // disclaimer in the documentation and/or other materials provided |
(...skipping 1886 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1897 HValue* src_index = AddUncasted<HAdd>(src_offset, index); | 1897 HValue* src_index = AddUncasted<HAdd>(src_offset, index); |
1898 HValue* value = | 1898 HValue* value = |
1899 AddUncasted<HSeqStringGetChar>(src_encoding, src, src_index); | 1899 AddUncasted<HSeqStringGetChar>(src_encoding, src, src_index); |
1900 HValue* dst_index = AddUncasted<HAdd>(dst_offset, index); | 1900 HValue* dst_index = AddUncasted<HAdd>(dst_offset, index); |
1901 Add<HSeqStringSetChar>(dst_encoding, dst, dst_index, value); | 1901 Add<HSeqStringSetChar>(dst_encoding, dst, dst_index, value); |
1902 } | 1902 } |
1903 loop.EndBody(); | 1903 loop.EndBody(); |
1904 } | 1904 } |
1905 | 1905 |
1906 | 1906 |
| 1907 HValue* HGraphBuilder::BuildObjectSizeAlignment( |
| 1908 HValue* unaligned_size, int header_size) { |
| 1909 ASSERT((header_size & kObjectAlignmentMask) == 0); |
| 1910 HValue* size = AddUncasted<HAdd>( |
| 1911 unaligned_size, Add<HConstant>(static_cast<int32_t>( |
| 1912 header_size + kObjectAlignmentMask))); |
| 1913 size->ClearFlag(HValue::kCanOverflow); |
| 1914 return AddUncasted<HBitwise>( |
| 1915 Token::BIT_AND, size, Add<HConstant>(static_cast<int32_t>( |
| 1916 ~kObjectAlignmentMask))); |
| 1917 } |
| 1918 |
| 1919 |
1907 HValue* HGraphBuilder::BuildUncheckedStringAdd( | 1920 HValue* HGraphBuilder::BuildUncheckedStringAdd( |
1908 HValue* left, | 1921 HValue* left, |
1909 HValue* right, | 1922 HValue* right, |
1910 HAllocationMode allocation_mode) { | 1923 HAllocationMode allocation_mode) { |
1911 // Determine the string lengths. | 1924 // Determine the string lengths. |
1912 HValue* left_length = AddLoadStringLength(left); | 1925 HValue* left_length = AddLoadStringLength(left); |
1913 HValue* right_length = AddLoadStringLength(right); | 1926 HValue* right_length = AddLoadStringLength(right); |
1914 | 1927 |
1915 // Compute the combined string length. | 1928 // Compute the combined string length. |
1916 HValue* length = BuildAddStringLengths(left_length, right_length); | 1929 HValue* length = BuildAddStringLengths(left_length, right_length); |
(...skipping 80 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1997 size->SetFlag(HValue::kUint32); | 2010 size->SetFlag(HValue::kUint32); |
1998 Push(size); | 2011 Push(size); |
1999 Push(string_map); | 2012 Push(string_map); |
2000 } | 2013 } |
2001 if_onebyte.End(); | 2014 if_onebyte.End(); |
2002 HValue* map = Pop(); | 2015 HValue* map = Pop(); |
2003 | 2016 |
2004 // Calculate the number of bytes needed for the characters in the | 2017 // Calculate the number of bytes needed for the characters in the |
2005 // string while observing object alignment. | 2018 // string while observing object alignment. |
2006 STATIC_ASSERT((SeqString::kHeaderSize & kObjectAlignmentMask) == 0); | 2019 STATIC_ASSERT((SeqString::kHeaderSize & kObjectAlignmentMask) == 0); |
2007 HValue* size = Pop(); | 2020 HValue* size = BuildObjectSizeAlignment(Pop(), SeqString::kHeaderSize); |
2008 size = AddUncasted<HAdd>(size, Add<HConstant>(static_cast<int32_t>( | |
2009 SeqString::kHeaderSize + kObjectAlignmentMask))); | |
2010 size->ClearFlag(HValue::kCanOverflow); | |
2011 size = AddUncasted<HBitwise>( | |
2012 Token::BIT_AND, size, Add<HConstant>(static_cast<int32_t>( | |
2013 ~kObjectAlignmentMask))); | |
2014 | 2021 |
2015 // Allocate the string object. HAllocate does not care whether we pass | 2022 // Allocate the string object. HAllocate does not care whether we pass |
2016 // STRING_TYPE or ASCII_STRING_TYPE here, so we just use STRING_TYPE here. | 2023 // STRING_TYPE or ASCII_STRING_TYPE here, so we just use STRING_TYPE here. |
2017 HAllocate* result = BuildAllocate( | 2024 HAllocate* result = BuildAllocate( |
2018 size, HType::String(), STRING_TYPE, allocation_mode); | 2025 size, HType::String(), STRING_TYPE, allocation_mode); |
2019 | 2026 |
2020 // We can safely skip the write barrier for storing map here. | 2027 // We can safely skip the write barrier for storing map here. |
2021 AddStoreMapNoWriteBarrier(result, map); | 2028 AddStoreMapNoWriteBarrier(result, map); |
2022 | 2029 |
2023 // Initialize the string fields. | 2030 // Initialize the string fields. |
(...skipping 4439 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
6463 HCompareMap* mapcompare = | 6470 HCompareMap* mapcompare = |
6464 New<HCompareMap>(object, map, this_map, other_map); | 6471 New<HCompareMap>(object, map, this_map, other_map); |
6465 FinishCurrentBlock(mapcompare); | 6472 FinishCurrentBlock(mapcompare); |
6466 | 6473 |
6467 set_current_block(this_map); | 6474 set_current_block(this_map); |
6468 HInstruction* access = NULL; | 6475 HInstruction* access = NULL; |
6469 if (IsDictionaryElementsKind(elements_kind)) { | 6476 if (IsDictionaryElementsKind(elements_kind)) { |
6470 access = AddInstruction(BuildKeyedGeneric(access_type, object, key, val)); | 6477 access = AddInstruction(BuildKeyedGeneric(access_type, object, key, val)); |
6471 } else { | 6478 } else { |
6472 ASSERT(IsFastElementsKind(elements_kind) || | 6479 ASSERT(IsFastElementsKind(elements_kind) || |
6473 IsExternalArrayElementsKind(elements_kind)); | 6480 IsExternalArrayElementsKind(elements_kind) || |
| 6481 IsFixedTypedArrayElementsKind(elements_kind)); |
6474 LoadKeyedHoleMode load_mode = BuildKeyedHoleMode(map); | 6482 LoadKeyedHoleMode load_mode = BuildKeyedHoleMode(map); |
6475 // Happily, mapcompare is a checked object. | 6483 // Happily, mapcompare is a checked object. |
6476 access = BuildUncheckedMonomorphicElementAccess( | 6484 access = BuildUncheckedMonomorphicElementAccess( |
6477 mapcompare, key, val, | 6485 mapcompare, key, val, |
6478 map->instance_type() == JS_ARRAY_TYPE, | 6486 map->instance_type() == JS_ARRAY_TYPE, |
6479 elements_kind, access_type, | 6487 elements_kind, access_type, |
6480 load_mode, | 6488 load_mode, |
6481 store_mode); | 6489 store_mode); |
6482 } | 6490 } |
6483 *has_side_effects |= access->HasObservableSideEffects(); | 6491 *has_side_effects |= access->HasObservableSideEffects(); |
(...skipping 1932 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
8416 for (int offset = ViewClass::kSize; | 8424 for (int offset = ViewClass::kSize; |
8417 offset < ViewClass::kSizeWithInternalFields; | 8425 offset < ViewClass::kSizeWithInternalFields; |
8418 offset += kPointerSize) { | 8426 offset += kPointerSize) { |
8419 Add<HStoreNamedField>(obj, | 8427 Add<HStoreNamedField>(obj, |
8420 HObjectAccess::ForObservableJSObjectOffset(offset), | 8428 HObjectAccess::ForObservableJSObjectOffset(offset), |
8421 graph()->GetConstant0()); | 8429 graph()->GetConstant0()); |
8422 } | 8430 } |
8423 | 8431 |
8424 Add<HStoreNamedField>( | 8432 Add<HStoreNamedField>( |
8425 obj, | 8433 obj, |
8426 HObjectAccess::ForJSArrayBufferViewBuffer(), buffer); | |
8427 Add<HStoreNamedField>( | |
8428 obj, | |
8429 HObjectAccess::ForJSArrayBufferViewByteOffset(), | 8434 HObjectAccess::ForJSArrayBufferViewByteOffset(), |
8430 byte_offset); | 8435 byte_offset); |
8431 Add<HStoreNamedField>( | 8436 Add<HStoreNamedField>( |
8432 obj, | 8437 obj, |
8433 HObjectAccess::ForJSArrayBufferViewByteLength(), | 8438 HObjectAccess::ForJSArrayBufferViewByteLength(), |
8434 byte_length); | 8439 byte_length); |
8435 | 8440 |
8436 HObjectAccess weak_first_view_access = | 8441 if (buffer != NULL) { |
8437 HObjectAccess::ForJSArrayBufferWeakFirstView(); | 8442 Add<HStoreNamedField>( |
8438 Add<HStoreNamedField>(obj, | 8443 obj, |
8439 HObjectAccess::ForJSArrayBufferViewWeakNext(), | 8444 HObjectAccess::ForJSArrayBufferViewBuffer(), buffer); |
8440 Add<HLoadNamedField>(buffer, static_cast<HValue*>(NULL), | 8445 HObjectAccess weak_first_view_access = |
8441 weak_first_view_access)); | 8446 HObjectAccess::ForJSArrayBufferWeakFirstView(); |
8442 Add<HStoreNamedField>( | 8447 Add<HStoreNamedField>(obj, |
8443 buffer, weak_first_view_access, obj); | 8448 HObjectAccess::ForJSArrayBufferViewWeakNext(), |
| 8449 Add<HLoadNamedField>(buffer, |
| 8450 static_cast<HValue*>(NULL), |
| 8451 weak_first_view_access)); |
| 8452 Add<HStoreNamedField>(buffer, weak_first_view_access, obj); |
| 8453 } else { |
| 8454 Add<HStoreNamedField>( |
| 8455 obj, |
| 8456 HObjectAccess::ForJSArrayBufferViewBuffer(), |
| 8457 Add<HConstant>(static_cast<int32_t>(0))); |
| 8458 Add<HStoreNamedField>(obj, |
| 8459 HObjectAccess::ForJSArrayBufferViewWeakNext(), |
| 8460 graph()->GetConstantUndefined()); |
| 8461 } |
8444 } | 8462 } |
8445 | 8463 |
8446 | 8464 |
8447 void HOptimizedGraphBuilder::GenerateDataViewInitialize( | 8465 void HOptimizedGraphBuilder::GenerateDataViewInitialize( |
8448 CallRuntime* expr) { | 8466 CallRuntime* expr) { |
8449 ZoneList<Expression*>* arguments = expr->arguments(); | 8467 ZoneList<Expression*>* arguments = expr->arguments(); |
8450 | 8468 |
8451 NoObservableSideEffectsScope scope(this); | 8469 NoObservableSideEffectsScope scope(this); |
8452 ASSERT(arguments->length()== 4); | 8470 ASSERT(arguments->length()== 4); |
8453 CHECK_ALIVE(VisitForValue(arguments->at(0))); | 8471 CHECK_ALIVE(VisitForValue(arguments->at(0))); |
8454 HValue* obj = Pop(); | 8472 HValue* obj = Pop(); |
8455 | 8473 |
8456 CHECK_ALIVE(VisitForValue(arguments->at(1))); | 8474 CHECK_ALIVE(VisitForValue(arguments->at(1))); |
8457 HValue* buffer = Pop(); | 8475 HValue* buffer = Pop(); |
8458 | 8476 |
8459 CHECK_ALIVE(VisitForValue(arguments->at(2))); | 8477 CHECK_ALIVE(VisitForValue(arguments->at(2))); |
8460 HValue* byte_offset = Pop(); | 8478 HValue* byte_offset = Pop(); |
8461 | 8479 |
8462 CHECK_ALIVE(VisitForValue(arguments->at(3))); | 8480 CHECK_ALIVE(VisitForValue(arguments->at(3))); |
8463 HValue* byte_length = Pop(); | 8481 HValue* byte_length = Pop(); |
8464 | 8482 |
8465 BuildArrayBufferViewInitialization<JSDataView>( | 8483 BuildArrayBufferViewInitialization<JSDataView>( |
8466 obj, buffer, byte_offset, byte_length); | 8484 obj, buffer, byte_offset, byte_length); |
8467 } | 8485 } |
8468 | 8486 |
8469 | 8487 |
| 8488 static Handle<Map> TypedArrayMap(Isolate* isolate, |
| 8489 ExternalArrayType array_type, |
| 8490 ElementsKind target_kind) { |
| 8491 Handle<Context> native_context = isolate->native_context(); |
| 8492 Handle<JSFunction> fun; |
| 8493 switch (array_type) { |
| 8494 #define TYPED_ARRAY_CASE(Type, type, TYPE, ctype, size) \ |
| 8495 case kExternal##Type##Array: \ |
| 8496 fun = Handle<JSFunction>(native_context->type##_array_fun()); \ |
| 8497 break; |
| 8498 |
| 8499 TYPED_ARRAYS(TYPED_ARRAY_CASE) |
| 8500 #undef TYPED_ARRAY_CASE |
| 8501 } |
| 8502 Handle<Map> map(fun->initial_map()); |
| 8503 return Map::AsElementsKind(map, target_kind); |
| 8504 } |
| 8505 |
| 8506 |
| 8507 HValue* HOptimizedGraphBuilder::BuildAllocateExternalElements( |
| 8508 ExternalArrayType array_type, |
| 8509 bool is_zero_byte_offset, |
| 8510 HValue* buffer, HValue* byte_offset, HValue* length) { |
| 8511 Handle<Map> external_array_map( |
| 8512 isolate()->heap()->MapForExternalArrayType(array_type)); |
| 8513 HValue* elements = |
| 8514 Add<HAllocate>( |
| 8515 Add<HConstant>(ExternalArray::kAlignedSize), |
| 8516 HType::Tagged(), |
| 8517 NOT_TENURED, |
| 8518 external_array_map->instance_type()); |
| 8519 |
| 8520 AddStoreMapConstant(elements, external_array_map); |
| 8521 |
| 8522 HValue* backing_store = Add<HLoadNamedField>( |
| 8523 buffer, static_cast<HValue*>(NULL), |
| 8524 HObjectAccess::ForJSArrayBufferBackingStore()); |
| 8525 |
| 8526 HValue* typed_array_start; |
| 8527 if (is_zero_byte_offset) { |
| 8528 typed_array_start = backing_store; |
| 8529 } else { |
| 8530 HInstruction* external_pointer = |
| 8531 AddUncasted<HAdd>(backing_store, byte_offset); |
| 8532 // Arguments are checked prior to call to TypedArrayInitialize, |
| 8533 // including byte_offset. |
| 8534 external_pointer->ClearFlag(HValue::kCanOverflow); |
| 8535 typed_array_start = external_pointer; |
| 8536 } |
| 8537 |
| 8538 |
| 8539 Add<HStoreNamedField>(elements, |
| 8540 HObjectAccess::ForExternalArrayExternalPointer(), |
| 8541 typed_array_start); |
| 8542 |
| 8543 Add<HStoreNamedField>(elements, |
| 8544 HObjectAccess::ForFixedArrayLength(), length); |
| 8545 return elements; |
| 8546 } |
| 8547 |
| 8548 |
| 8549 HValue* HOptimizedGraphBuilder::BuildAllocateFixedTypedArray( |
| 8550 ExternalArrayType array_type, size_t element_size, |
| 8551 ElementsKind fixed_elements_kind, |
| 8552 HValue* byte_length, HValue* length) { |
| 8553 STATIC_ASSERT( |
| 8554 (FixedTypedArrayBase::kHeaderSize & kObjectAlignmentMask) == 0); |
| 8555 HValue* total_size; |
| 8556 |
| 8557 // if fixed array's elements are not aligned to object's alignment, |
| 8558 // we need to align the whole array to object alignment. |
| 8559 if (element_size % kObjectAlignment != 0) { |
| 8560 total_size = BuildObjectSizeAlignment( |
| 8561 byte_length, FixedTypedArrayBase::kHeaderSize); |
| 8562 } else { |
| 8563 total_size = AddUncasted<HAdd>(byte_length, |
| 8564 Add<HConstant>(FixedTypedArrayBase::kHeaderSize)); |
| 8565 total_size->ClearFlag(HValue::kCanOverflow); |
| 8566 } |
| 8567 |
| 8568 Handle<Map> fixed_typed_array_map( |
| 8569 isolate()->heap()->MapForFixedTypedArray(array_type)); |
| 8570 HValue* elements = |
| 8571 Add<HAllocate>(total_size, HType::Tagged(), |
| 8572 NOT_TENURED, |
| 8573 fixed_typed_array_map->instance_type()); |
| 8574 AddStoreMapConstant(elements, fixed_typed_array_map); |
| 8575 |
| 8576 Add<HStoreNamedField>(elements, |
| 8577 HObjectAccess::ForFixedArrayLength(), |
| 8578 length); |
| 8579 HValue* filler = Add<HConstant>(static_cast<int32_t>(0)); |
| 8580 |
| 8581 { |
| 8582 LoopBuilder builder(this, context(), LoopBuilder::kPostIncrement); |
| 8583 |
| 8584 HValue* key = builder.BeginBody( |
| 8585 Add<HConstant>(static_cast<int32_t>(0)), |
| 8586 length, Token::LT); |
| 8587 Add<HStoreKeyed>(elements, key, filler, fixed_elements_kind); |
| 8588 |
| 8589 builder.EndBody(); |
| 8590 } |
| 8591 Add<HStoreNamedField>( |
| 8592 elements, HObjectAccess::ForFixedArrayLength(), length); |
| 8593 return elements; |
| 8594 } |
| 8595 |
| 8596 |
8470 void HOptimizedGraphBuilder::GenerateTypedArrayInitialize( | 8597 void HOptimizedGraphBuilder::GenerateTypedArrayInitialize( |
8471 CallRuntime* expr) { | 8598 CallRuntime* expr) { |
8472 ZoneList<Expression*>* arguments = expr->arguments(); | 8599 ZoneList<Expression*>* arguments = expr->arguments(); |
8473 | 8600 |
8474 NoObservableSideEffectsScope scope(this); | 8601 NoObservableSideEffectsScope scope(this); |
8475 static const int kObjectArg = 0; | 8602 static const int kObjectArg = 0; |
8476 static const int kArrayIdArg = 1; | 8603 static const int kArrayIdArg = 1; |
8477 static const int kBufferArg = 2; | 8604 static const int kBufferArg = 2; |
8478 static const int kByteOffsetArg = 3; | 8605 static const int kByteOffsetArg = 3; |
8479 static const int kByteLengthArg = 4; | 8606 static const int kByteLengthArg = 4; |
8480 static const int kArgsLength = 5; | 8607 static const int kArgsLength = 5; |
8481 ASSERT(arguments->length() == kArgsLength); | 8608 ASSERT(arguments->length() == kArgsLength); |
8482 | 8609 |
8483 | 8610 |
8484 CHECK_ALIVE(VisitForValue(arguments->at(kObjectArg))); | 8611 CHECK_ALIVE(VisitForValue(arguments->at(kObjectArg))); |
8485 HValue* obj = Pop(); | 8612 HValue* obj = Pop(); |
8486 | 8613 |
8487 ASSERT(arguments->at(kArrayIdArg)->node_type() == AstNode::kLiteral); | 8614 ASSERT(arguments->at(kArrayIdArg)->node_type() == AstNode::kLiteral); |
8488 Handle<Object> value = | 8615 Handle<Object> value = |
8489 static_cast<Literal*>(arguments->at(kArrayIdArg))->value(); | 8616 static_cast<Literal*>(arguments->at(kArrayIdArg))->value(); |
8490 ASSERT(value->IsSmi()); | 8617 ASSERT(value->IsSmi()); |
8491 int array_id = Smi::cast(*value)->value(); | 8618 int array_id = Smi::cast(*value)->value(); |
8492 | 8619 |
8493 CHECK_ALIVE(VisitForValue(arguments->at(kBufferArg))); | 8620 HValue* buffer; |
8494 HValue* buffer = Pop(); | 8621 if (!arguments->at(kBufferArg)->IsNullLiteral()) { |
| 8622 CHECK_ALIVE(VisitForValue(arguments->at(kBufferArg))); |
| 8623 buffer = Pop(); |
| 8624 } else { |
| 8625 buffer = NULL; |
| 8626 } |
8495 | 8627 |
8496 HValue* byte_offset; | 8628 HValue* byte_offset; |
8497 bool is_zero_byte_offset; | 8629 bool is_zero_byte_offset; |
8498 | 8630 |
8499 if (arguments->at(kByteOffsetArg)->node_type() == AstNode::kLiteral | 8631 if (arguments->at(kByteOffsetArg)->node_type() == AstNode::kLiteral |
8500 && Smi::FromInt(0) == | 8632 && Smi::FromInt(0) == |
8501 *static_cast<Literal*>(arguments->at(kByteOffsetArg))->value()) { | 8633 *static_cast<Literal*>(arguments->at(kByteOffsetArg))->value()) { |
8502 byte_offset = Add<HConstant>(static_cast<int32_t>(0)); | 8634 byte_offset = Add<HConstant>(static_cast<int32_t>(0)); |
8503 is_zero_byte_offset = true; | 8635 is_zero_byte_offset = true; |
8504 } else { | 8636 } else { |
8505 CHECK_ALIVE(VisitForValue(arguments->at(kByteOffsetArg))); | 8637 CHECK_ALIVE(VisitForValue(arguments->at(kByteOffsetArg))); |
8506 byte_offset = Pop(); | 8638 byte_offset = Pop(); |
8507 is_zero_byte_offset = false; | 8639 is_zero_byte_offset = false; |
| 8640 ASSERT(buffer != NULL); |
8508 } | 8641 } |
8509 | 8642 |
8510 CHECK_ALIVE(VisitForValue(arguments->at(kByteLengthArg))); | 8643 CHECK_ALIVE(VisitForValue(arguments->at(kByteLengthArg))); |
8511 HValue* byte_length = Pop(); | 8644 HValue* byte_length = Pop(); |
8512 | 8645 |
8513 IfBuilder byte_offset_smi(this); | 8646 IfBuilder byte_offset_smi(this); |
8514 | 8647 |
8515 if (!is_zero_byte_offset) { | 8648 if (!is_zero_byte_offset) { |
8516 byte_offset_smi.If<HIsSmiAndBranch>(byte_offset); | 8649 byte_offset_smi.If<HIsSmiAndBranch>(byte_offset); |
8517 byte_offset_smi.Then(); | 8650 byte_offset_smi.Then(); |
8518 } | 8651 } |
8519 | 8652 |
| 8653 ExternalArrayType array_type = |
| 8654 kExternalInt8Array; // Bogus initialization. |
| 8655 size_t element_size = 1; // Bogus initialization. |
| 8656 ElementsKind external_elements_kind = // Bogus initialization. |
| 8657 EXTERNAL_INT8_ELEMENTS; |
| 8658 ElementsKind fixed_elements_kind = // Bogus initialization. |
| 8659 INT8_ELEMENTS; |
| 8660 Runtime::ArrayIdToTypeAndSize(array_id, |
| 8661 &array_type, |
| 8662 &external_elements_kind, |
| 8663 &fixed_elements_kind, |
| 8664 &element_size); |
| 8665 |
| 8666 |
8520 { // byte_offset is Smi. | 8667 { // byte_offset is Smi. |
8521 BuildArrayBufferViewInitialization<JSTypedArray>( | 8668 BuildArrayBufferViewInitialization<JSTypedArray>( |
8522 obj, buffer, byte_offset, byte_length); | 8669 obj, buffer, byte_offset, byte_length); |
8523 | 8670 |
8524 ExternalArrayType array_type = kExternalInt8Array; // Bogus initialization. | |
8525 size_t element_size = 1; // Bogus initialization. | |
8526 Runtime::ArrayIdToTypeAndSize(array_id, &array_type, &element_size); | |
8527 | 8671 |
8528 HInstruction* length = AddUncasted<HDiv>(byte_length, | 8672 HInstruction* length = AddUncasted<HDiv>(byte_length, |
8529 Add<HConstant>(static_cast<int32_t>(element_size))); | 8673 Add<HConstant>(static_cast<int32_t>(element_size))); |
8530 | 8674 |
8531 Add<HStoreNamedField>(obj, | 8675 Add<HStoreNamedField>(obj, |
8532 HObjectAccess::ForJSTypedArrayLength(), | 8676 HObjectAccess::ForJSTypedArrayLength(), |
8533 length); | 8677 length); |
8534 | 8678 |
8535 Handle<Map> external_array_map( | 8679 HValue* elements; |
8536 isolate()->heap()->MapForExternalArrayType(array_type)); | 8680 if (buffer != NULL) { |
8537 | 8681 elements = BuildAllocateExternalElements( |
8538 HValue* elements = | 8682 array_type, is_zero_byte_offset, buffer, byte_offset, length); |
8539 Add<HAllocate>( | 8683 Handle<Map> obj_map = TypedArrayMap( |
8540 Add<HConstant>(ExternalArray::kAlignedSize), | 8684 isolate(), array_type, external_elements_kind); |
8541 HType::Tagged(), | 8685 AddStoreMapConstant(obj, obj_map); |
8542 NOT_TENURED, | |
8543 external_array_map->instance_type()); | |
8544 | |
8545 AddStoreMapConstant(elements, external_array_map); | |
8546 | |
8547 HValue* backing_store = Add<HLoadNamedField>( | |
8548 buffer, static_cast<HValue*>(NULL), | |
8549 HObjectAccess::ForJSArrayBufferBackingStore()); | |
8550 | |
8551 HValue* typed_array_start; | |
8552 if (is_zero_byte_offset) { | |
8553 typed_array_start = backing_store; | |
8554 } else { | 8686 } else { |
8555 HInstruction* external_pointer = | 8687 ASSERT(is_zero_byte_offset); |
8556 AddUncasted<HAdd>(backing_store, byte_offset); | 8688 elements = BuildAllocateFixedTypedArray( |
8557 // Arguments are checked prior to call to TypedArrayInitialize, | 8689 array_type, element_size, fixed_elements_kind, |
8558 // including byte_offset. | 8690 byte_length, length); |
8559 external_pointer->ClearFlag(HValue::kCanOverflow); | |
8560 typed_array_start = external_pointer; | |
8561 } | 8691 } |
8562 | |
8563 Add<HStoreNamedField>(elements, | |
8564 HObjectAccess::ForExternalArrayExternalPointer(), | |
8565 typed_array_start); | |
8566 Add<HStoreNamedField>(elements, | |
8567 HObjectAccess::ForFixedArrayLength(), | |
8568 length); | |
8569 Add<HStoreNamedField>( | 8692 Add<HStoreNamedField>( |
8570 obj, HObjectAccess::ForElementsPointer(), elements); | 8693 obj, HObjectAccess::ForElementsPointer(), elements); |
8571 } | 8694 } |
8572 | 8695 |
8573 if (!is_zero_byte_offset) { | 8696 if (!is_zero_byte_offset) { |
8574 byte_offset_smi.Else(); | 8697 byte_offset_smi.Else(); |
8575 { // byte_offset is not Smi. | 8698 { // byte_offset is not Smi. |
8576 Push(obj); | 8699 Push(obj); |
8577 CHECK_ALIVE(VisitForValue(arguments->at(kArrayIdArg))); | 8700 CHECK_ALIVE(VisitForValue(arguments->at(kArrayIdArg))); |
8578 Push(buffer); | 8701 Push(buffer); |
8579 Push(byte_offset); | 8702 Push(byte_offset); |
8580 Push(byte_length); | 8703 Push(byte_length); |
8581 PushArgumentsFromEnvironment(kArgsLength); | 8704 PushArgumentsFromEnvironment(kArgsLength); |
8582 Add<HCallRuntime>(expr->name(), expr->function(), kArgsLength); | 8705 Add<HCallRuntime>(expr->name(), expr->function(), kArgsLength); |
8583 } | 8706 } |
8584 } | 8707 } |
8585 byte_offset_smi.End(); | 8708 byte_offset_smi.End(); |
8586 } | 8709 } |
8587 | 8710 |
8588 | 8711 |
8589 void HOptimizedGraphBuilder::GenerateMaxSmi(CallRuntime* expr) { | 8712 void HOptimizedGraphBuilder::GenerateMaxSmi(CallRuntime* expr) { |
8590 ASSERT(expr->arguments()->length() == 0); | 8713 ASSERT(expr->arguments()->length() == 0); |
8591 HConstant* max_smi = New<HConstant>(static_cast<int32_t>(Smi::kMaxValue)); | 8714 HConstant* max_smi = New<HConstant>(static_cast<int32_t>(Smi::kMaxValue)); |
8592 return ast_context()->ReturnInstruction(max_smi, expr->id()); | 8715 return ast_context()->ReturnInstruction(max_smi, expr->id()); |
8593 } | 8716 } |
8594 | 8717 |
8595 | 8718 |
| 8719 void HOptimizedGraphBuilder::GenerateTypedArrayMaxSizeInHeap( |
| 8720 CallRuntime* expr) { |
| 8721 ASSERT(expr->arguments()->length() == 0); |
| 8722 HConstant* result = New<HConstant>(static_cast<int32_t>( |
| 8723 FLAG_typed_array_max_size_in_heap)); |
| 8724 return ast_context()->ReturnInstruction(result, expr->id()); |
| 8725 } |
| 8726 |
| 8727 |
8596 void HOptimizedGraphBuilder::VisitCallRuntime(CallRuntime* expr) { | 8728 void HOptimizedGraphBuilder::VisitCallRuntime(CallRuntime* expr) { |
8597 ASSERT(!HasStackOverflow()); | 8729 ASSERT(!HasStackOverflow()); |
8598 ASSERT(current_block() != NULL); | 8730 ASSERT(current_block() != NULL); |
8599 ASSERT(current_block()->HasPredecessor()); | 8731 ASSERT(current_block()->HasPredecessor()); |
8600 if (expr->is_jsruntime()) { | 8732 if (expr->is_jsruntime()) { |
8601 return Bailout(kCallToAJavaScriptRuntimeFunction); | 8733 return Bailout(kCallToAJavaScriptRuntimeFunction); |
8602 } | 8734 } |
8603 | 8735 |
8604 const Runtime::Function* function = expr->function(); | 8736 const Runtime::Function* function = expr->function(); |
8605 ASSERT(function != NULL); | 8737 ASSERT(function != NULL); |
(...skipping 2705 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
11311 if (ShouldProduceTraceOutput()) { | 11443 if (ShouldProduceTraceOutput()) { |
11312 isolate()->GetHTracer()->TraceHydrogen(name(), graph_); | 11444 isolate()->GetHTracer()->TraceHydrogen(name(), graph_); |
11313 } | 11445 } |
11314 | 11446 |
11315 #ifdef DEBUG | 11447 #ifdef DEBUG |
11316 graph_->Verify(false); // No full verify. | 11448 graph_->Verify(false); // No full verify. |
11317 #endif | 11449 #endif |
11318 } | 11450 } |
11319 | 11451 |
11320 } } // namespace v8::internal | 11452 } } // namespace v8::internal |
OLD | NEW |