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 7997 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
8068 &HOptimizedGraphBuilder::Generate##Name, | 8069 &HOptimizedGraphBuilder::Generate##Name, |
8069 | 8070 |
8070 const HOptimizedGraphBuilder::InlineFunctionGenerator | 8071 const HOptimizedGraphBuilder::InlineFunctionGenerator |
8071 HOptimizedGraphBuilder::kInlineFunctionGenerators[] = { | 8072 HOptimizedGraphBuilder::kInlineFunctionGenerators[] = { |
8072 INLINE_FUNCTION_LIST(INLINE_FUNCTION_GENERATOR_ADDRESS) | 8073 INLINE_FUNCTION_LIST(INLINE_FUNCTION_GENERATOR_ADDRESS) |
8073 INLINE_RUNTIME_FUNCTION_LIST(INLINE_FUNCTION_GENERATOR_ADDRESS) | 8074 INLINE_RUNTIME_FUNCTION_LIST(INLINE_FUNCTION_GENERATOR_ADDRESS) |
8074 }; | 8075 }; |
8075 #undef INLINE_FUNCTION_GENERATOR_ADDRESS | 8076 #undef INLINE_FUNCTION_GENERATOR_ADDRESS |
8076 | 8077 |
8077 | 8078 |
| 8079 template <class ViewClass> |
| 8080 void HGraphBuilder::BuildArrayBufferViewInitialization( |
| 8081 HValue* obj, |
| 8082 HValue* buffer, |
| 8083 HValue* byte_offset, |
| 8084 HValue* byte_length) { |
| 8085 |
| 8086 for (int offset = ViewClass::kSize; |
| 8087 offset < ViewClass::kSizeWithInternalFields; |
| 8088 offset += kPointerSize) { |
| 8089 Add<HStoreNamedField>(obj, |
| 8090 HObjectAccess::ForJSObjectOffset(offset), |
| 8091 Add<HConstant>(static_cast<int32_t>(0))); |
| 8092 } |
| 8093 |
| 8094 Add<HStoreNamedField>( |
| 8095 obj, |
| 8096 HObjectAccess::ForJSArrayBufferViewBuffer(), buffer); |
| 8097 Add<HStoreNamedField>( |
| 8098 obj, |
| 8099 HObjectAccess::ForJSArrayBufferViewByteOffset(), |
| 8100 byte_offset); |
| 8101 Add<HStoreNamedField>( |
| 8102 obj, |
| 8103 HObjectAccess::ForJSArrayBufferViewByteLength(), |
| 8104 byte_length); |
| 8105 |
| 8106 HObjectAccess weak_first_view_access = |
| 8107 HObjectAccess::ForJSArrayBufferWeakFirstView(); |
| 8108 Add<HStoreNamedField>(obj, |
| 8109 HObjectAccess::ForJSArrayBufferViewWeakNext(), |
| 8110 Add<HLoadNamedField>(buffer, weak_first_view_access)); |
| 8111 Add<HStoreNamedField>(buffer, weak_first_view_access, obj); |
| 8112 } |
| 8113 |
| 8114 |
8078 void HOptimizedGraphBuilder::VisitDataViewInitialize( | 8115 void HOptimizedGraphBuilder::VisitDataViewInitialize( |
8079 CallRuntime* expr) { | 8116 CallRuntime* expr) { |
8080 ZoneList<Expression*>* arguments = expr->arguments(); | 8117 ZoneList<Expression*>* arguments = expr->arguments(); |
8081 | 8118 |
8082 NoObservableSideEffectsScope scope(this); | 8119 NoObservableSideEffectsScope scope(this); |
8083 ASSERT(arguments->length()== 4); | 8120 ASSERT(arguments->length()== 4); |
8084 CHECK_ALIVE(VisitForValue(arguments->at(0))); | 8121 CHECK_ALIVE(VisitForValue(arguments->at(0))); |
8085 HValue* obj = Pop(); | 8122 HValue* obj = Pop(); |
8086 | 8123 |
8087 CHECK_ALIVE(VisitForValue(arguments->at(1))); | 8124 CHECK_ALIVE(VisitForValue(arguments->at(1))); |
8088 HValue* buffer = Pop(); | 8125 HValue* buffer = Pop(); |
8089 | 8126 |
8090 CHECK_ALIVE(VisitForValue(arguments->at(2))); | 8127 CHECK_ALIVE(VisitForValue(arguments->at(2))); |
8091 HValue* byte_offset = Pop(); | 8128 HValue* byte_offset = Pop(); |
8092 | 8129 |
8093 CHECK_ALIVE(VisitForValue(arguments->at(3))); | 8130 CHECK_ALIVE(VisitForValue(arguments->at(3))); |
8094 HValue* byte_length = Pop(); | 8131 HValue* byte_length = Pop(); |
8095 | 8132 |
8096 for (int offset = JSDataView::kSize; | 8133 BuildArrayBufferViewInitialization<JSDataView>( |
8097 offset < JSDataView::kSizeWithInternalFields; | 8134 obj, buffer, byte_offset, byte_length); |
8098 offset += kPointerSize) { | |
8099 Add<HStoreNamedField>(obj, | |
8100 HObjectAccess::ForJSObjectOffset(offset), | |
8101 Add<HConstant>(static_cast<int32_t>(0))); | |
8102 } | |
8103 | |
8104 Add<HStoreNamedField>(obj, | |
8105 HObjectAccess::ForJSObjectOffset(JSDataView::kBufferOffset), buffer); | |
8106 Add<HStoreNamedField>(obj, | |
8107 HObjectAccess::ForJSObjectOffset(JSDataView::kByteOffsetOffset), | |
8108 byte_offset); | |
8109 Add<HStoreNamedField>(obj, | |
8110 HObjectAccess::ForJSObjectOffset(JSDataView::kByteLengthOffset), | |
8111 byte_length); | |
8112 | |
8113 Add<HStoreNamedField>(obj, | |
8114 HObjectAccess::ForJSObjectOffset(JSDataView::kWeakNextOffset), | |
8115 Add<HLoadNamedField>(buffer, | |
8116 HObjectAccess::ForJSObjectOffset( | |
8117 JSArrayBuffer::kWeakFirstViewOffset))); | |
8118 Add<HStoreNamedField>(buffer, | |
8119 HObjectAccess::ForJSObjectOffset(JSArrayBuffer::kWeakFirstViewOffset), | |
8120 obj); | |
8121 } | 8135 } |
8122 | 8136 |
8123 | 8137 |
| 8138 void HOptimizedGraphBuilder::VisitTypedArrayInitialize( |
| 8139 CallRuntime* expr) { |
| 8140 ZoneList<Expression*>* arguments = expr->arguments(); |
| 8141 |
| 8142 NoObservableSideEffectsScope scope(this); |
| 8143 static const int kObjectArg = 0; |
| 8144 static const int kArrayIdArg = 1; |
| 8145 static const int kBufferArg = 2; |
| 8146 static const int kByteOffsetArg = 3; |
| 8147 static const int kByteLengthArg = 4; |
| 8148 static const int kArgsLength = 5; |
| 8149 ASSERT(arguments->length() == kArgsLength); |
| 8150 |
| 8151 |
| 8152 CHECK_ALIVE(VisitForValue(arguments->at(kObjectArg))); |
| 8153 HValue* obj = Pop(); |
| 8154 |
| 8155 ASSERT(arguments->at(kArrayIdArg)->node_type() == AstNode::kLiteral); |
| 8156 Handle<Object> value = |
| 8157 static_cast<Literal*>(arguments->at(kArrayIdArg))->value(); |
| 8158 ASSERT(value->IsSmi()); |
| 8159 int array_id = Smi::cast(*value)->value(); |
| 8160 |
| 8161 CHECK_ALIVE(VisitForValue(arguments->at(kBufferArg))); |
| 8162 HValue* buffer = Pop(); |
| 8163 |
| 8164 HValue* byte_offset; |
| 8165 bool is_zero_byte_offset; |
| 8166 |
| 8167 if (arguments->at(kByteOffsetArg)->node_type() == AstNode::kLiteral |
| 8168 && Smi::FromInt(0) == |
| 8169 *static_cast<Literal*>(arguments->at(kByteOffsetArg))->value()) { |
| 8170 byte_offset = Add<HConstant>(static_cast<int32_t>(0)); |
| 8171 is_zero_byte_offset = true; |
| 8172 } else { |
| 8173 CHECK_ALIVE(VisitForValue(arguments->at(kByteOffsetArg))); |
| 8174 byte_offset = Pop(); |
| 8175 is_zero_byte_offset = false; |
| 8176 } |
| 8177 |
| 8178 CHECK_ALIVE(VisitForValue(arguments->at(kByteLengthArg))); |
| 8179 HValue* byte_length = Pop(); |
| 8180 |
| 8181 IfBuilder byte_offset_smi(this); |
| 8182 |
| 8183 if (!is_zero_byte_offset) { |
| 8184 byte_offset_smi.If<HIsSmiAndBranch>(byte_offset); |
| 8185 byte_offset_smi.Then(); |
| 8186 } |
| 8187 |
| 8188 { // byte_offset is Smi. |
| 8189 BuildArrayBufferViewInitialization<JSTypedArray>( |
| 8190 obj, buffer, byte_offset, byte_length); |
| 8191 |
| 8192 ExternalArrayType array_type = kExternalByteArray; // Bogus initialization. |
| 8193 size_t element_size = 1; // Bogus initialization. |
| 8194 Runtime::ArrayIdToTypeAndSize(array_id, &array_type, &element_size); |
| 8195 |
| 8196 HInstruction* length = AddUncasted<HDiv>(byte_length, |
| 8197 Add<HConstant>(static_cast<int32_t>(element_size))); |
| 8198 |
| 8199 Add<HStoreNamedField>(obj, |
| 8200 HObjectAccess::ForJSTypedArrayLength(), |
| 8201 length); |
| 8202 |
| 8203 HValue* elements = |
| 8204 Add<HAllocate>( |
| 8205 Add<HConstant>(ExternalArray::kAlignedSize), |
| 8206 HType::JSArray(), |
| 8207 NOT_TENURED, |
| 8208 static_cast<InstanceType>(FIRST_EXTERNAL_ARRAY_TYPE + array_type)); |
| 8209 |
| 8210 Handle<Map> external_array_map( |
| 8211 isolate()->heap()->MapForExternalArrayType(array_type)); |
| 8212 Add<HStoreNamedField>(elements, |
| 8213 HObjectAccess::ForMap(), |
| 8214 Add<HConstant>(external_array_map)); |
| 8215 |
| 8216 HValue* backing_store = Add<HLoadNamedField>( |
| 8217 buffer, HObjectAccess::ForJSArrayBufferBackingStore()); |
| 8218 |
| 8219 HValue* typed_array_start; |
| 8220 if (is_zero_byte_offset) { |
| 8221 typed_array_start = backing_store; |
| 8222 } else { |
| 8223 HInstruction* external_pointer = |
| 8224 AddUncasted<HAdd>(backing_store, byte_offset); |
| 8225 // Arguments are checked prior to call to TypedArrayInitialize, |
| 8226 // including byte_offset. |
| 8227 external_pointer->ClearFlag(HValue::kCanOverflow); |
| 8228 typed_array_start = external_pointer; |
| 8229 } |
| 8230 |
| 8231 Add<HStoreNamedField>(elements, |
| 8232 HObjectAccess::ForExternalArrayExternalPointer(), |
| 8233 typed_array_start); |
| 8234 Add<HStoreNamedField>(elements, |
| 8235 HObjectAccess::ForFixedArrayLength(), |
| 8236 length); |
| 8237 Add<HStoreNamedField>( |
| 8238 obj, HObjectAccess::ForElementsPointer(), elements); |
| 8239 } |
| 8240 |
| 8241 if (!is_zero_byte_offset) { |
| 8242 byte_offset_smi.Else(); |
| 8243 { // byte_offset is not Smi. |
| 8244 Push(Add<HPushArgument>(obj)); |
| 8245 VisitArgument(arguments->at(kArrayIdArg)); |
| 8246 Push(Add<HPushArgument>(buffer)); |
| 8247 Push(Add<HPushArgument>(byte_offset)); |
| 8248 Push(Add<HPushArgument>(byte_length)); |
| 8249 Add<HCallRuntime>(expr->name(), expr->function(), kArgsLength); |
| 8250 Drop(kArgsLength); |
| 8251 } |
| 8252 } |
| 8253 byte_offset_smi.End(); |
| 8254 } |
| 8255 |
| 8256 |
8124 void HOptimizedGraphBuilder::VisitCallRuntime(CallRuntime* expr) { | 8257 void HOptimizedGraphBuilder::VisitCallRuntime(CallRuntime* expr) { |
8125 ASSERT(!HasStackOverflow()); | 8258 ASSERT(!HasStackOverflow()); |
8126 ASSERT(current_block() != NULL); | 8259 ASSERT(current_block() != NULL); |
8127 ASSERT(current_block()->HasPredecessor()); | 8260 ASSERT(current_block()->HasPredecessor()); |
8128 if (expr->is_jsruntime()) { | 8261 if (expr->is_jsruntime()) { |
8129 return Bailout(kCallToAJavaScriptRuntimeFunction); | 8262 return Bailout(kCallToAJavaScriptRuntimeFunction); |
8130 } | 8263 } |
8131 | 8264 |
8132 const Runtime::Function* function = expr->function(); | 8265 const Runtime::Function* function = expr->function(); |
8133 ASSERT(function != NULL); | 8266 ASSERT(function != NULL); |
8134 | 8267 |
8135 if (function->function_id == Runtime::kDataViewInitialize) { | 8268 if (function->function_id == Runtime::kDataViewInitialize) { |
8136 return VisitDataViewInitialize(expr); | 8269 return VisitDataViewInitialize(expr); |
8137 } | 8270 } |
8138 | 8271 |
| 8272 if (function->function_id == Runtime::kTypedArrayInitialize) { |
| 8273 return VisitTypedArrayInitialize(expr); |
| 8274 } |
| 8275 |
| 8276 if (function->function_id == Runtime::kMaxSmi) { |
| 8277 ASSERT(expr->arguments()->length() == 0); |
| 8278 HConstant* max_smi = New<HConstant>(static_cast<int32_t>(Smi::kMaxValue)); |
| 8279 return ast_context()->ReturnInstruction(max_smi, expr->id()); |
| 8280 } |
| 8281 |
8139 if (function->intrinsic_type == Runtime::INLINE) { | 8282 if (function->intrinsic_type == Runtime::INLINE) { |
8140 ASSERT(expr->name()->length() > 0); | 8283 ASSERT(expr->name()->length() > 0); |
8141 ASSERT(expr->name()->Get(0) == '_'); | 8284 ASSERT(expr->name()->Get(0) == '_'); |
8142 // Call to an inline function. | 8285 // Call to an inline function. |
8143 int lookup_index = static_cast<int>(function->function_id) - | 8286 int lookup_index = static_cast<int>(function->function_id) - |
8144 static_cast<int>(Runtime::kFirstInlineFunction); | 8287 static_cast<int>(Runtime::kFirstInlineFunction); |
8145 ASSERT(lookup_index >= 0); | 8288 ASSERT(lookup_index >= 0); |
8146 ASSERT(static_cast<size_t>(lookup_index) < | 8289 ASSERT(static_cast<size_t>(lookup_index) < |
8147 ARRAY_SIZE(kInlineFunctionGenerators)); | 8290 ARRAY_SIZE(kInlineFunctionGenerators)); |
8148 InlineFunctionGenerator generator = kInlineFunctionGenerators[lookup_index]; | 8291 InlineFunctionGenerator generator = kInlineFunctionGenerators[lookup_index]; |
(...skipping 2516 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
10665 if (ShouldProduceTraceOutput()) { | 10808 if (ShouldProduceTraceOutput()) { |
10666 isolate()->GetHTracer()->TraceHydrogen(name(), graph_); | 10809 isolate()->GetHTracer()->TraceHydrogen(name(), graph_); |
10667 } | 10810 } |
10668 | 10811 |
10669 #ifdef DEBUG | 10812 #ifdef DEBUG |
10670 graph_->Verify(false); // No full verify. | 10813 graph_->Verify(false); // No full verify. |
10671 #endif | 10814 #endif |
10672 } | 10815 } |
10673 | 10816 |
10674 } } // namespace v8::internal | 10817 } } // namespace v8::internal |
OLD | NEW |