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