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 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
51 #include "hydrogen-minus-zero.h" | 51 #include "hydrogen-minus-zero.h" |
52 #include "hydrogen-osr.h" | 52 #include "hydrogen-osr.h" |
53 #include "hydrogen-range-analysis.h" | 53 #include "hydrogen-range-analysis.h" |
54 #include "hydrogen-redundant-phi.h" | 54 #include "hydrogen-redundant-phi.h" |
55 #include "hydrogen-removable-simulates.h" | 55 #include "hydrogen-removable-simulates.h" |
56 #include "hydrogen-representation-changes.h" | 56 #include "hydrogen-representation-changes.h" |
57 #include "hydrogen-sce.h" | 57 #include "hydrogen-sce.h" |
58 #include "hydrogen-uint32-analysis.h" | 58 #include "hydrogen-uint32-analysis.h" |
59 #include "lithium-allocator.h" | 59 #include "lithium-allocator.h" |
60 #include "parser.h" | 60 #include "parser.h" |
| 61 #include "runtime.h" |
61 #include "scopeinfo.h" | 62 #include "scopeinfo.h" |
62 #include "scopes.h" | 63 #include "scopes.h" |
63 #include "stub-cache.h" | 64 #include "stub-cache.h" |
64 #include "typing.h" | 65 #include "typing.h" |
65 | 66 |
66 #if V8_TARGET_ARCH_IA32 | 67 #if V8_TARGET_ARCH_IA32 |
67 #include "ia32/lithium-codegen-ia32.h" | 68 #include "ia32/lithium-codegen-ia32.h" |
68 #elif V8_TARGET_ARCH_X64 | 69 #elif V8_TARGET_ARCH_X64 |
69 #include "x64/lithium-codegen-x64.h" | 70 #include "x64/lithium-codegen-x64.h" |
70 #elif V8_TARGET_ARCH_ARM | 71 #elif V8_TARGET_ARCH_ARM |
(...skipping 7974 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
8045 &HOptimizedGraphBuilder::Generate##Name, | 8046 &HOptimizedGraphBuilder::Generate##Name, |
8046 | 8047 |
8047 const HOptimizedGraphBuilder::InlineFunctionGenerator | 8048 const HOptimizedGraphBuilder::InlineFunctionGenerator |
8048 HOptimizedGraphBuilder::kInlineFunctionGenerators[] = { | 8049 HOptimizedGraphBuilder::kInlineFunctionGenerators[] = { |
8049 INLINE_FUNCTION_LIST(INLINE_FUNCTION_GENERATOR_ADDRESS) | 8050 INLINE_FUNCTION_LIST(INLINE_FUNCTION_GENERATOR_ADDRESS) |
8050 INLINE_RUNTIME_FUNCTION_LIST(INLINE_FUNCTION_GENERATOR_ADDRESS) | 8051 INLINE_RUNTIME_FUNCTION_LIST(INLINE_FUNCTION_GENERATOR_ADDRESS) |
8051 }; | 8052 }; |
8052 #undef INLINE_FUNCTION_GENERATOR_ADDRESS | 8053 #undef INLINE_FUNCTION_GENERATOR_ADDRESS |
8053 | 8054 |
8054 | 8055 |
| 8056 template <class ViewClass> |
| 8057 void BuildArrayBufferViewInitialization( |
| 8058 HGraphBuilder* graph, |
| 8059 HValue* obj, |
| 8060 HValue* buffer, |
| 8061 HValue* byte_offset, |
| 8062 HValue* byte_length) { |
| 8063 |
| 8064 for (int offset = ViewClass::kSize; |
| 8065 offset < ViewClass::kSizeWithInternalFields; |
| 8066 offset += kPointerSize) { |
| 8067 graph->Add<HStoreNamedField>(obj, |
| 8068 HObjectAccess::ForJSObjectOffset(offset), |
| 8069 graph->Add<HConstant>(static_cast<int32_t>(0))); |
| 8070 } |
| 8071 |
| 8072 graph->Add<HStoreNamedField>(obj, |
| 8073 HObjectAccess::ForJSObjectOffset(ViewClass::kBufferOffset), buffer); |
| 8074 graph->Add<HStoreNamedField>(obj, |
| 8075 HObjectAccess::ForJSObjectOffset(ViewClass::kByteOffsetOffset), |
| 8076 byte_offset); |
| 8077 graph->Add<HStoreNamedField>(obj, |
| 8078 HObjectAccess::ForJSObjectOffset(ViewClass::kByteLengthOffset), |
| 8079 byte_length); |
| 8080 |
| 8081 graph->Add<HStoreNamedField>(obj, |
| 8082 HObjectAccess::ForJSObjectOffset(ViewClass::kWeakNextOffset), |
| 8083 graph->Add<HLoadNamedField>(buffer, |
| 8084 HObjectAccess::ForJSObjectOffset( |
| 8085 JSArrayBuffer::kWeakFirstViewOffset))); |
| 8086 graph->Add<HStoreNamedField>(buffer, |
| 8087 HObjectAccess::ForJSObjectOffset(JSArrayBuffer::kWeakFirstViewOffset), |
| 8088 obj); |
| 8089 } |
| 8090 |
| 8091 |
8055 void HOptimizedGraphBuilder::VisitDataViewInitialize( | 8092 void HOptimizedGraphBuilder::VisitDataViewInitialize( |
8056 CallRuntime* expr) { | 8093 CallRuntime* expr) { |
8057 ZoneList<Expression*>* arguments = expr->arguments(); | 8094 ZoneList<Expression*>* arguments = expr->arguments(); |
8058 | 8095 |
8059 NoObservableSideEffectsScope scope(this); | 8096 NoObservableSideEffectsScope scope(this); |
8060 ASSERT(arguments->length()== 4); | 8097 ASSERT(arguments->length()== 4); |
8061 CHECK_ALIVE(VisitForValue(arguments->at(0))); | 8098 CHECK_ALIVE(VisitForValue(arguments->at(0))); |
8062 HValue* obj = Pop(); | 8099 HValue* obj = Pop(); |
8063 | 8100 |
8064 CHECK_ALIVE(VisitForValue(arguments->at(1))); | 8101 CHECK_ALIVE(VisitForValue(arguments->at(1))); |
8065 HValue* buffer = Pop(); | 8102 HValue* buffer = Pop(); |
8066 | 8103 |
8067 CHECK_ALIVE(VisitForValue(arguments->at(2))); | 8104 CHECK_ALIVE(VisitForValue(arguments->at(2))); |
8068 HValue* byte_offset = Pop(); | 8105 HValue* byte_offset = Pop(); |
8069 | 8106 |
8070 CHECK_ALIVE(VisitForValue(arguments->at(3))); | 8107 CHECK_ALIVE(VisitForValue(arguments->at(3))); |
8071 HValue* byte_length = Pop(); | 8108 HValue* byte_length = Pop(); |
8072 | 8109 |
8073 for (int offset = JSDataView::kSize; | 8110 BuildArrayBufferViewInitialization<JSDataView>( |
8074 offset < JSDataView::kSizeWithInternalFields; | 8111 this, obj, buffer, byte_offset, byte_length); |
8075 offset += kPointerSize) { | |
8076 Add<HStoreNamedField>(obj, | |
8077 HObjectAccess::ForJSObjectOffset(offset), | |
8078 Add<HConstant>(static_cast<int32_t>(0))); | |
8079 } | |
8080 | |
8081 Add<HStoreNamedField>(obj, | |
8082 HObjectAccess::ForJSObjectOffset(JSDataView::kBufferOffset), buffer); | |
8083 Add<HStoreNamedField>(obj, | |
8084 HObjectAccess::ForJSObjectOffset(JSDataView::kByteOffsetOffset), | |
8085 byte_offset); | |
8086 Add<HStoreNamedField>(obj, | |
8087 HObjectAccess::ForJSObjectOffset(JSDataView::kByteLengthOffset), | |
8088 byte_length); | |
8089 | |
8090 Add<HStoreNamedField>(obj, | |
8091 HObjectAccess::ForJSObjectOffset(JSDataView::kWeakNextOffset), | |
8092 Add<HLoadNamedField>(buffer, | |
8093 HObjectAccess::ForJSObjectOffset( | |
8094 JSArrayBuffer::kWeakFirstViewOffset))); | |
8095 Add<HStoreNamedField>(buffer, | |
8096 HObjectAccess::ForJSObjectOffset(JSArrayBuffer::kWeakFirstViewOffset), | |
8097 obj); | |
8098 } | 8112 } |
8099 | 8113 |
8100 | 8114 |
| 8115 void HOptimizedGraphBuilder::VisitTypedArrayInitialize( |
| 8116 CallRuntime* expr) { |
| 8117 ZoneList<Expression*>* arguments = expr->arguments(); |
| 8118 |
| 8119 NoObservableSideEffectsScope scope(this); |
| 8120 static const int kObjectArg = 0; |
| 8121 static const int kArrayIdArg = 1; |
| 8122 static const int kBufferArg = 2; |
| 8123 static const int kByteOffsetArg = 3; |
| 8124 static const int kByteLengthArg = 4; |
| 8125 static const int kArgsLength = 5; |
| 8126 ASSERT(arguments->length() == kArgsLength); |
| 8127 |
| 8128 |
| 8129 CHECK_ALIVE(VisitForValue(arguments->at(kObjectArg))); |
| 8130 HValue* obj = Pop(); |
| 8131 |
| 8132 ASSERT(arguments->at(kArrayIdArg)->node_type() == AstNode::kLiteral); |
| 8133 Handle<Object> value = |
| 8134 static_cast<Literal*>(arguments->at(kArrayIdArg))->value(); |
| 8135 ASSERT(value->IsSmi()); |
| 8136 int array_id = Smi::cast(*value)->value(); |
| 8137 |
| 8138 CHECK_ALIVE(VisitForValue(arguments->at(kBufferArg))); |
| 8139 HValue* buffer = Pop(); |
| 8140 |
| 8141 HValue* byte_offset; |
| 8142 bool is_zero_byte_offset; |
| 8143 |
| 8144 if (arguments->at(kByteOffsetArg)->node_type() == AstNode::kLiteral |
| 8145 && Smi::FromInt(0) == |
| 8146 *static_cast<Literal*>(arguments->at(kByteOffsetArg))->value()) { |
| 8147 byte_offset = Add<HConstant>(static_cast<int32_t>(0)); |
| 8148 is_zero_byte_offset = true; |
| 8149 } else { |
| 8150 CHECK_ALIVE(VisitForValue(arguments->at(kByteOffsetArg))); |
| 8151 byte_offset = Pop(); |
| 8152 is_zero_byte_offset = false; |
| 8153 } |
| 8154 |
| 8155 CHECK_ALIVE(VisitForValue(arguments->at(kByteLengthArg))); |
| 8156 HValue* byte_length = Pop(); |
| 8157 |
| 8158 IfBuilder byte_offset_smi(this); |
| 8159 |
| 8160 if (!is_zero_byte_offset) { |
| 8161 byte_offset_smi.If<HIsSmiAndBranch>(byte_offset); |
| 8162 byte_offset_smi.Then(); |
| 8163 } |
| 8164 |
| 8165 { // byte_offset is Smi. |
| 8166 BuildArrayBufferViewInitialization<JSTypedArray>( |
| 8167 this, obj, buffer, byte_offset, byte_length); |
| 8168 |
| 8169 ExternalArrayType array_type = kExternalByteArray; // Bogus initialization. |
| 8170 size_t element_size = 1; // Bogus initialization. |
| 8171 Runtime::ArrayIdToTypeAndSize(array_id, &array_type, &element_size); |
| 8172 |
| 8173 HInstruction* length = Add<HDiv>(byte_length, |
| 8174 Add<HConstant>(static_cast<int32_t>(element_size))); |
| 8175 |
| 8176 Add<HStoreNamedField>(obj, |
| 8177 HObjectAccess::ForJSObjectOffset(JSTypedArray::kLengthOffset), |
| 8178 length); |
| 8179 |
| 8180 HValue* elements = |
| 8181 Add<HAllocate>( |
| 8182 Add<HConstant>(ExternalArray::kAlignedSize), |
| 8183 HType::JSArray(), |
| 8184 NOT_TENURED, |
| 8185 static_cast<InstanceType>(FIRST_EXTERNAL_ARRAY_TYPE + array_type)); |
| 8186 |
| 8187 Handle<Map> external_array_map( |
| 8188 isolate()->heap()->MapForExternalArrayType(array_type)); |
| 8189 |
| 8190 Add<HStoreNamedField>(elements, |
| 8191 HObjectAccess::ForMap(), |
| 8192 Add<HConstant>(external_array_map)); |
| 8193 HValue* backing_store = |
| 8194 Add<HLoadNamedField>(buffer, |
| 8195 HObjectAccess::ForJSObjectOffset( |
| 8196 JSArrayBuffer::kBackingStoreOffset, Representation::External())); |
| 8197 |
| 8198 HValue* typed_array_start; |
| 8199 if (is_zero_byte_offset) { |
| 8200 typed_array_start = backing_store; |
| 8201 } else { |
| 8202 HInstruction* external_pointer = |
| 8203 HAdd::New( |
| 8204 zone(), graph()->GetInvalidContext(), backing_store, byte_offset, |
| 8205 Representation::External()); |
| 8206 // Arguments are checked prior to call to TypedArrayInitialize, |
| 8207 // including byte_offset. |
| 8208 external_pointer->ClearFlag(HValue::kCanOverflow); |
| 8209 typed_array_start = AddInstruction(external_pointer); |
| 8210 } |
| 8211 |
| 8212 Add<HStoreNamedField>(elements, |
| 8213 HObjectAccess::ForJSObjectOffset( |
| 8214 ExternalArray::kExternalPointerOffset, Representation::External()), |
| 8215 typed_array_start); |
| 8216 Add<HStoreNamedField>(elements, |
| 8217 HObjectAccess::ForJSObjectOffset(ExternalArray::kLengthOffset), |
| 8218 length); |
| 8219 Add<HStoreNamedField>( |
| 8220 obj, HObjectAccess::ForElementsPointer(), elements); |
| 8221 } |
| 8222 |
| 8223 if (!is_zero_byte_offset) { |
| 8224 byte_offset_smi.Else(); |
| 8225 { // byte_offset is not Smi. |
| 8226 Push(Add<HPushArgument>(obj)); |
| 8227 VisitArgument(arguments->at(kArrayIdArg)); |
| 8228 Push(Add<HPushArgument>(buffer)); |
| 8229 Push(Add<HPushArgument>(byte_offset)); |
| 8230 Push(Add<HPushArgument>(byte_length)); |
| 8231 Add<HCallRuntime>(expr->name(), expr->function(), kArgsLength); |
| 8232 Drop(kArgsLength); |
| 8233 } |
| 8234 byte_offset_smi.End(); |
| 8235 } |
| 8236 } |
| 8237 |
| 8238 |
8101 void HOptimizedGraphBuilder::VisitCallRuntime(CallRuntime* expr) { | 8239 void HOptimizedGraphBuilder::VisitCallRuntime(CallRuntime* expr) { |
8102 ASSERT(!HasStackOverflow()); | 8240 ASSERT(!HasStackOverflow()); |
8103 ASSERT(current_block() != NULL); | 8241 ASSERT(current_block() != NULL); |
8104 ASSERT(current_block()->HasPredecessor()); | 8242 ASSERT(current_block()->HasPredecessor()); |
8105 if (expr->is_jsruntime()) { | 8243 if (expr->is_jsruntime()) { |
8106 return Bailout(kCallToAJavaScriptRuntimeFunction); | 8244 return Bailout(kCallToAJavaScriptRuntimeFunction); |
8107 } | 8245 } |
8108 | 8246 |
8109 const Runtime::Function* function = expr->function(); | 8247 const Runtime::Function* function = expr->function(); |
8110 ASSERT(function != NULL); | 8248 ASSERT(function != NULL); |
8111 | 8249 |
8112 if (function->function_id == Runtime::kDataViewInitialize) { | 8250 if (function->function_id == Runtime::kDataViewInitialize) { |
8113 return VisitDataViewInitialize(expr); | 8251 return VisitDataViewInitialize(expr); |
8114 } | 8252 } |
8115 | 8253 |
| 8254 if (function->function_id == Runtime::kTypedArrayInitialize) { |
| 8255 return VisitTypedArrayInitialize(expr); |
| 8256 } |
| 8257 |
| 8258 if (function->function_id == Runtime::kMaxSmi) { |
| 8259 ASSERT(expr->arguments()->length() == 0); |
| 8260 HConstant* max_smi = New<HConstant>(static_cast<int32_t>(Smi::kMaxValue)); |
| 8261 return ast_context()->ReturnInstruction(max_smi, expr->id()); |
| 8262 } |
| 8263 |
8116 if (function->intrinsic_type == Runtime::INLINE) { | 8264 if (function->intrinsic_type == Runtime::INLINE) { |
8117 ASSERT(expr->name()->length() > 0); | 8265 ASSERT(expr->name()->length() > 0); |
8118 ASSERT(expr->name()->Get(0) == '_'); | 8266 ASSERT(expr->name()->Get(0) == '_'); |
8119 // Call to an inline function. | 8267 // Call to an inline function. |
8120 int lookup_index = static_cast<int>(function->function_id) - | 8268 int lookup_index = static_cast<int>(function->function_id) - |
8121 static_cast<int>(Runtime::kFirstInlineFunction); | 8269 static_cast<int>(Runtime::kFirstInlineFunction); |
8122 ASSERT(lookup_index >= 0); | 8270 ASSERT(lookup_index >= 0); |
8123 ASSERT(static_cast<size_t>(lookup_index) < | 8271 ASSERT(static_cast<size_t>(lookup_index) < |
8124 ARRAY_SIZE(kInlineFunctionGenerators)); | 8272 ARRAY_SIZE(kInlineFunctionGenerators)); |
8125 InlineFunctionGenerator generator = kInlineFunctionGenerators[lookup_index]; | 8273 InlineFunctionGenerator generator = kInlineFunctionGenerators[lookup_index]; |
(...skipping 2494 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
10620 if (ShouldProduceTraceOutput()) { | 10768 if (ShouldProduceTraceOutput()) { |
10621 isolate()->GetHTracer()->TraceHydrogen(name(), graph_); | 10769 isolate()->GetHTracer()->TraceHydrogen(name(), graph_); |
10622 } | 10770 } |
10623 | 10771 |
10624 #ifdef DEBUG | 10772 #ifdef DEBUG |
10625 graph_->Verify(false); // No full verify. | 10773 graph_->Verify(false); // No full verify. |
10626 #endif | 10774 #endif |
10627 } | 10775 } |
10628 | 10776 |
10629 } } // namespace v8::internal | 10777 } } // namespace v8::internal |
OLD | NEW |