Chromium Code Reviews| 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 7976 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 8047 &HOptimizedGraphBuilder::Generate##Name, | 8048 &HOptimizedGraphBuilder::Generate##Name, |
| 8048 | 8049 |
| 8049 const HOptimizedGraphBuilder::InlineFunctionGenerator | 8050 const HOptimizedGraphBuilder::InlineFunctionGenerator |
| 8050 HOptimizedGraphBuilder::kInlineFunctionGenerators[] = { | 8051 HOptimizedGraphBuilder::kInlineFunctionGenerators[] = { |
| 8051 INLINE_FUNCTION_LIST(INLINE_FUNCTION_GENERATOR_ADDRESS) | 8052 INLINE_FUNCTION_LIST(INLINE_FUNCTION_GENERATOR_ADDRESS) |
| 8052 INLINE_RUNTIME_FUNCTION_LIST(INLINE_FUNCTION_GENERATOR_ADDRESS) | 8053 INLINE_RUNTIME_FUNCTION_LIST(INLINE_FUNCTION_GENERATOR_ADDRESS) |
| 8053 }; | 8054 }; |
| 8054 #undef INLINE_FUNCTION_GENERATOR_ADDRESS | 8055 #undef INLINE_FUNCTION_GENERATOR_ADDRESS |
| 8055 | 8056 |
| 8056 | 8057 |
| 8058 template <class ViewClass> | |
| 8059 void HGraphBuilder::BuildArrayBufferViewInitialization( | |
| 8060 HValue* obj, | |
| 8061 HValue* buffer, | |
| 8062 HValue* byte_offset, | |
| 8063 HValue* byte_length) { | |
| 8064 | |
| 8065 for (int offset = ViewClass::kSize; | |
| 8066 offset < ViewClass::kSizeWithInternalFields; | |
| 8067 offset += kPointerSize) { | |
| 8068 Add<HStoreNamedField>(obj, | |
| 8069 HObjectAccess::ForJSObjectOffset(offset), | |
| 8070 Add<HConstant>(static_cast<int32_t>(0))); | |
| 8071 } | |
| 8072 | |
| 8073 Add<HStoreNamedField>(obj, | |
| 8074 HObjectAccess::ForJSObjectOffset(ViewClass::kBufferOffset), buffer); | |
| 8075 Add<HStoreNamedField>(obj, | |
| 8076 HObjectAccess::ForJSObjectOffset(ViewClass::kByteOffsetOffset), | |
| 8077 byte_offset); | |
| 8078 Add<HStoreNamedField>(obj, | |
| 8079 HObjectAccess::ForJSObjectOffset(ViewClass::kByteLengthOffset), | |
| 8080 byte_length); | |
| 8081 | |
| 8082 HObjectAccess weak_first_view_access = | |
| 8083 HObjectAccess::ForJSObjectOffset(JSArrayBuffer::kWeakFirstViewOffset); | |
| 8084 Add<HStoreNamedField>(obj, | |
| 8085 HObjectAccess::ForJSObjectOffset(ViewClass::kWeakNextOffset), | |
| 8086 Add<HLoadNamedField>(buffer, weak_first_view_access)); | |
| 8087 Add<HStoreNamedField>(buffer, weak_first_view_access, obj); | |
| 8088 } | |
| 8089 | |
| 8090 | |
| 8057 void HOptimizedGraphBuilder::VisitDataViewInitialize( | 8091 void HOptimizedGraphBuilder::VisitDataViewInitialize( |
| 8058 CallRuntime* expr) { | 8092 CallRuntime* expr) { |
| 8059 ZoneList<Expression*>* arguments = expr->arguments(); | 8093 ZoneList<Expression*>* arguments = expr->arguments(); |
| 8060 | 8094 |
| 8061 NoObservableSideEffectsScope scope(this); | 8095 NoObservableSideEffectsScope scope(this); |
| 8062 ASSERT(arguments->length()== 4); | 8096 ASSERT(arguments->length()== 4); |
| 8063 CHECK_ALIVE(VisitForValue(arguments->at(0))); | 8097 CHECK_ALIVE(VisitForValue(arguments->at(0))); |
| 8064 HValue* obj = Pop(); | 8098 HValue* obj = Pop(); |
| 8065 | 8099 |
| 8066 CHECK_ALIVE(VisitForValue(arguments->at(1))); | 8100 CHECK_ALIVE(VisitForValue(arguments->at(1))); |
| 8067 HValue* buffer = Pop(); | 8101 HValue* buffer = Pop(); |
| 8068 | 8102 |
| 8069 CHECK_ALIVE(VisitForValue(arguments->at(2))); | 8103 CHECK_ALIVE(VisitForValue(arguments->at(2))); |
| 8070 HValue* byte_offset = Pop(); | 8104 HValue* byte_offset = Pop(); |
| 8071 | 8105 |
| 8072 CHECK_ALIVE(VisitForValue(arguments->at(3))); | 8106 CHECK_ALIVE(VisitForValue(arguments->at(3))); |
| 8073 HValue* byte_length = Pop(); | 8107 HValue* byte_length = Pop(); |
| 8074 | 8108 |
| 8075 for (int offset = JSDataView::kSize; | 8109 BuildArrayBufferViewInitialization<JSDataView>( |
| 8076 offset < JSDataView::kSizeWithInternalFields; | 8110 obj, buffer, byte_offset, byte_length); |
| 8077 offset += kPointerSize) { | |
| 8078 Add<HStoreNamedField>(obj, | |
| 8079 HObjectAccess::ForJSObjectOffset(offset), | |
| 8080 Add<HConstant>(static_cast<int32_t>(0))); | |
| 8081 } | |
| 8082 | |
| 8083 Add<HStoreNamedField>(obj, | |
| 8084 HObjectAccess::ForJSObjectOffset(JSDataView::kBufferOffset), buffer); | |
| 8085 Add<HStoreNamedField>(obj, | |
| 8086 HObjectAccess::ForJSObjectOffset(JSDataView::kByteOffsetOffset), | |
| 8087 byte_offset); | |
| 8088 Add<HStoreNamedField>(obj, | |
| 8089 HObjectAccess::ForJSObjectOffset(JSDataView::kByteLengthOffset), | |
| 8090 byte_length); | |
| 8091 | |
| 8092 Add<HStoreNamedField>(obj, | |
| 8093 HObjectAccess::ForJSObjectOffset(JSDataView::kWeakNextOffset), | |
| 8094 Add<HLoadNamedField>(buffer, | |
| 8095 HObjectAccess::ForJSObjectOffset( | |
| 8096 JSArrayBuffer::kWeakFirstViewOffset))); | |
| 8097 Add<HStoreNamedField>(buffer, | |
| 8098 HObjectAccess::ForJSObjectOffset(JSArrayBuffer::kWeakFirstViewOffset), | |
| 8099 obj); | |
| 8100 } | 8111 } |
| 8101 | 8112 |
| 8102 | 8113 |
| 8114 void HOptimizedGraphBuilder::VisitTypedArrayInitialize( | |
| 8115 CallRuntime* expr) { | |
| 8116 ZoneList<Expression*>* arguments = expr->arguments(); | |
| 8117 | |
| 8118 NoObservableSideEffectsScope scope(this); | |
| 8119 static const int kObjectArg = 0; | |
| 8120 static const int kArrayIdArg = 1; | |
| 8121 static const int kBufferArg = 2; | |
| 8122 static const int kByteOffsetArg = 3; | |
| 8123 static const int kByteLengthArg = 4; | |
| 8124 static const int kArgsLength = 5; | |
| 8125 ASSERT(arguments->length() == kArgsLength); | |
| 8126 | |
| 8127 | |
| 8128 CHECK_ALIVE(VisitForValue(arguments->at(kObjectArg))); | |
| 8129 HValue* obj = Pop(); | |
| 8130 | |
| 8131 ASSERT(arguments->at(kArrayIdArg)->node_type() == AstNode::kLiteral); | |
| 8132 Handle<Object> value = | |
| 8133 static_cast<Literal*>(arguments->at(kArrayIdArg))->value(); | |
| 8134 ASSERT(value->IsSmi()); | |
| 8135 int array_id = Smi::cast(*value)->value(); | |
| 8136 | |
| 8137 CHECK_ALIVE(VisitForValue(arguments->at(kBufferArg))); | |
| 8138 HValue* buffer = Pop(); | |
| 8139 | |
| 8140 HValue* byte_offset; | |
| 8141 bool is_zero_byte_offset; | |
| 8142 | |
| 8143 if (arguments->at(kByteOffsetArg)->node_type() == AstNode::kLiteral | |
| 8144 && Smi::FromInt(0) == | |
| 8145 *static_cast<Literal*>(arguments->at(kByteOffsetArg))->value()) { | |
| 8146 byte_offset = Add<HConstant>(static_cast<int32_t>(0)); | |
| 8147 is_zero_byte_offset = true; | |
| 8148 } else { | |
| 8149 CHECK_ALIVE(VisitForValue(arguments->at(kByteOffsetArg))); | |
| 8150 byte_offset = Pop(); | |
| 8151 is_zero_byte_offset = false; | |
| 8152 } | |
| 8153 | |
| 8154 CHECK_ALIVE(VisitForValue(arguments->at(kByteLengthArg))); | |
| 8155 HValue* byte_length = Pop(); | |
| 8156 | |
| 8157 IfBuilder byte_offset_smi(this); | |
| 8158 | |
| 8159 if (!is_zero_byte_offset) { | |
| 8160 byte_offset_smi.If<HIsSmiAndBranch>(byte_offset); | |
| 8161 byte_offset_smi.Then(); | |
| 8162 } | |
| 8163 | |
| 8164 { // byte_offset is Smi. | |
| 8165 BuildArrayBufferViewInitialization<JSTypedArray>( | |
| 8166 obj, buffer, byte_offset, byte_length); | |
| 8167 | |
| 8168 ExternalArrayType array_type = kExternalByteArray; // Bogus initialization. | |
| 8169 size_t element_size = 1; // Bogus initialization. | |
| 8170 Runtime::ArrayIdToTypeAndSize(array_id, &array_type, &element_size); | |
| 8171 | |
| 8172 HInstruction* length = AddUncasted<HDiv>(byte_length, | |
| 8173 Add<HConstant>(static_cast<int32_t>(element_size))); | |
| 8174 | |
| 8175 Add<HStoreNamedField>(obj, | |
| 8176 HObjectAccess::ForJSObjectOffset(JSTypedArray::kLengthOffset), | |
|
danno
2013/11/21 20:44:35
Here an elsewhere, does it perhaps make sense to w
Dmitry Lomov (no reviews)
2013/11/22 12:40:27
Done, albeit reluctantly. I see the value of encap
| |
| 8177 length); | |
| 8178 | |
| 8179 HValue* elements = | |
| 8180 Add<HAllocate>( | |
|
danno
2013/11/21 20:44:35
nit: 4 char indent
Dmitry Lomov (no reviews)
2013/11/22 12:40:27
Done.
| |
| 8181 Add<HConstant>(ExternalArray::kAlignedSize), | |
| 8182 HType::JSArray(), | |
| 8183 NOT_TENURED, | |
| 8184 static_cast<InstanceType>(FIRST_EXTERNAL_ARRAY_TYPE + array_type)); | |
| 8185 | |
| 8186 Handle<Map> external_array_map( | |
| 8187 isolate()->heap()->MapForExternalArrayType(array_type)); | |
| 8188 | |
|
danno
2013/11/21 20:44:35
nit: Group the load/store pairs and their preparat
Dmitry Lomov (no reviews)
2013/11/22 12:40:27
Done.
| |
| 8189 Add<HStoreNamedField>(elements, | |
| 8190 HObjectAccess::ForMap(), | |
| 8191 Add<HConstant>(external_array_map)); | |
|
danno
2013/11/21 20:44:35
nit: And insert one after this line
Dmitry Lomov (no reviews)
2013/11/22 12:40:27
Done.
| |
| 8192 HObjectAccess backing_store_access = | |
| 8193 HObjectAccess::ForJSObjectOffset( | |
| 8194 JSArrayBuffer::kBackingStoreOffset, Representation::External()); | |
| 8195 | |
|
danno
2013/11/21 20:44:35
nit: remove this line
Dmitry Lomov (no reviews)
2013/11/22 12:40:27
Done.
| |
| 8196 HValue* backing_store = Add<HLoadNamedField>(buffer, backing_store_access); | |
| 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 AddUncasted<HAdd>(backing_store, byte_offset); | |
| 8204 // Arguments are checked prior to call to TypedArrayInitialize, | |
| 8205 // including byte_offset. | |
| 8206 external_pointer->ClearFlag(HValue::kCanOverflow); | |
| 8207 typed_array_start = external_pointer; | |
| 8208 } | |
| 8209 | |
| 8210 Add<HStoreNamedField>(elements, | |
| 8211 HObjectAccess::ForJSObjectOffset( | |
| 8212 ExternalArray::kExternalPointerOffset, Representation::External()), | |
| 8213 typed_array_start); | |
| 8214 Add<HStoreNamedField>(elements, | |
| 8215 HObjectAccess::ForJSObjectOffset(ExternalArray::kLengthOffset), | |
|
danno
2013/11/21 20:44:35
I think it's safe to use HObjectAccoess::ForFixedA
| |
| 8216 length); | |
| 8217 Add<HStoreNamedField>( | |
| 8218 obj, HObjectAccess::ForElementsPointer(), elements); | |
| 8219 } | |
| 8220 | |
| 8221 if (!is_zero_byte_offset) { | |
| 8222 byte_offset_smi.Else(); | |
| 8223 { // byte_offset is not Smi. | |
| 8224 Push(Add<HPushArgument>(obj)); | |
| 8225 VisitArgument(arguments->at(kArrayIdArg)); | |
| 8226 Push(Add<HPushArgument>(buffer)); | |
| 8227 Push(Add<HPushArgument>(byte_offset)); | |
| 8228 Push(Add<HPushArgument>(byte_length)); | |
| 8229 Add<HCallRuntime>(expr->name(), expr->function(), kArgsLength); | |
| 8230 Drop(kArgsLength); | |
| 8231 } | |
| 8232 } | |
| 8233 byte_offset_smi.End(); | |
| 8234 } | |
| 8235 | |
| 8236 | |
| 8103 void HOptimizedGraphBuilder::VisitCallRuntime(CallRuntime* expr) { | 8237 void HOptimizedGraphBuilder::VisitCallRuntime(CallRuntime* expr) { |
| 8104 ASSERT(!HasStackOverflow()); | 8238 ASSERT(!HasStackOverflow()); |
| 8105 ASSERT(current_block() != NULL); | 8239 ASSERT(current_block() != NULL); |
| 8106 ASSERT(current_block()->HasPredecessor()); | 8240 ASSERT(current_block()->HasPredecessor()); |
| 8107 if (expr->is_jsruntime()) { | 8241 if (expr->is_jsruntime()) { |
| 8108 return Bailout(kCallToAJavaScriptRuntimeFunction); | 8242 return Bailout(kCallToAJavaScriptRuntimeFunction); |
| 8109 } | 8243 } |
| 8110 | 8244 |
| 8111 const Runtime::Function* function = expr->function(); | 8245 const Runtime::Function* function = expr->function(); |
| 8112 ASSERT(function != NULL); | 8246 ASSERT(function != NULL); |
| 8113 | 8247 |
| 8114 if (function->function_id == Runtime::kDataViewInitialize) { | 8248 if (function->function_id == Runtime::kDataViewInitialize) { |
| 8115 return VisitDataViewInitialize(expr); | 8249 return VisitDataViewInitialize(expr); |
| 8116 } | 8250 } |
| 8117 | 8251 |
| 8252 if (function->function_id == Runtime::kTypedArrayInitialize) { | |
| 8253 return VisitTypedArrayInitialize(expr); | |
| 8254 } | |
| 8255 | |
| 8256 if (function->function_id == Runtime::kMaxSmi) { | |
| 8257 ASSERT(expr->arguments()->length() == 0); | |
| 8258 HConstant* max_smi = New<HConstant>(static_cast<int32_t>(Smi::kMaxValue)); | |
| 8259 return ast_context()->ReturnInstruction(max_smi, expr->id()); | |
| 8260 } | |
| 8261 | |
| 8118 if (function->intrinsic_type == Runtime::INLINE) { | 8262 if (function->intrinsic_type == Runtime::INLINE) { |
| 8119 ASSERT(expr->name()->length() > 0); | 8263 ASSERT(expr->name()->length() > 0); |
| 8120 ASSERT(expr->name()->Get(0) == '_'); | 8264 ASSERT(expr->name()->Get(0) == '_'); |
| 8121 // Call to an inline function. | 8265 // Call to an inline function. |
| 8122 int lookup_index = static_cast<int>(function->function_id) - | 8266 int lookup_index = static_cast<int>(function->function_id) - |
| 8123 static_cast<int>(Runtime::kFirstInlineFunction); | 8267 static_cast<int>(Runtime::kFirstInlineFunction); |
| 8124 ASSERT(lookup_index >= 0); | 8268 ASSERT(lookup_index >= 0); |
| 8125 ASSERT(static_cast<size_t>(lookup_index) < | 8269 ASSERT(static_cast<size_t>(lookup_index) < |
| 8126 ARRAY_SIZE(kInlineFunctionGenerators)); | 8270 ARRAY_SIZE(kInlineFunctionGenerators)); |
| 8127 InlineFunctionGenerator generator = kInlineFunctionGenerators[lookup_index]; | 8271 InlineFunctionGenerator generator = kInlineFunctionGenerators[lookup_index]; |
| (...skipping 2495 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 10623 if (ShouldProduceTraceOutput()) { | 10767 if (ShouldProduceTraceOutput()) { |
| 10624 isolate()->GetHTracer()->TraceHydrogen(name(), graph_); | 10768 isolate()->GetHTracer()->TraceHydrogen(name(), graph_); |
| 10625 } | 10769 } |
| 10626 | 10770 |
| 10627 #ifdef DEBUG | 10771 #ifdef DEBUG |
| 10628 graph_->Verify(false); // No full verify. | 10772 graph_->Verify(false); // No full verify. |
| 10629 #endif | 10773 #endif |
| 10630 } | 10774 } |
| 10631 | 10775 |
| 10632 } } // namespace v8::internal | 10776 } } // namespace v8::internal |
| OLD | NEW |