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 void HOptimizedGraphBuilder::VisitTypedArrayInitialize( | |
8057 CallRuntime* expr) { | |
8058 ZoneList<Expression*>* arguments = expr->arguments(); | |
8059 | |
8060 NoObservableSideEffectsScope scope(this); | |
8061 ASSERT(arguments->length()== 5); | |
8062 CHECK_ALIVE(VisitForValue(arguments->at(0))); | |
8063 HValue* obj = Pop(); | |
8064 | |
8065 ASSERT(arguments->at(1)->node_type() == AstNode::kLiteral); | |
mvstanton
2013/11/18 10:44:49
Could you use constants for these arguments with a
Dmitry Lomov (no reviews)
2013/11/18 13:48:14
Done. Great suggestion, because it uncovered a bug
| |
8066 Handle<Object> value = static_cast<Literal*>(arguments->at(1))->value(); | |
8067 ASSERT(value->IsSmi()); | |
mvstanton
2013/11/18 10:44:49
The assert is unnecessary because the Smi::cast wi
Dmitry Lomov (no reviews)
2013/11/18 13:48:14
I am paranoid lately.
| |
8068 int array_id = Smi::cast(*value)->value(); | |
8069 | |
8070 CHECK_ALIVE(VisitForValue(arguments->at(2))); | |
8071 HValue* buffer = Pop(); | |
8072 | |
8073 HValue* byte_offset; | |
8074 bool is_zero_byte_offset; | |
8075 | |
8076 if (arguments->at(3)->node_type() == AstNode::kLiteral | |
8077 && Smi::FromInt(0) == *static_cast<Literal*>(arguments->at(1))->value()) { | |
8078 byte_offset = Add<HConstant>(static_cast<int32_t>(0)); | |
8079 is_zero_byte_offset = true; | |
8080 } else { | |
8081 CHECK_ALIVE(VisitForValue(arguments->at(3))); | |
8082 byte_offset = Pop(); | |
8083 is_zero_byte_offset = false; | |
8084 } | |
8085 | |
8086 CHECK_ALIVE(VisitForValue(arguments->at(4))); | |
8087 HValue* byte_length = Pop(); | |
8088 | |
8089 IfBuilder byte_offset_smi(this); | |
8090 | |
8091 if (!is_zero_byte_offset) { | |
8092 byte_offset_smi.If<HIsSmiAndBranch>(byte_offset); | |
8093 byte_offset_smi.Then(); | |
8094 } | |
8095 | |
8096 ExternalArrayType array_type = kExternalByteArray; // Bogus initialization. | |
8097 size_t element_size = 1; // Bogus initialization. | |
8098 Runtime::ArrayIdToTypeAndSize(array_id, &array_type, &element_size); | |
8099 | |
8100 for (int offset = JSTypedArray::kSize; | |
8101 offset < JSTypedArray::kSizeWithInternalFields; | |
8102 offset += kPointerSize) { | |
8103 Add<HStoreNamedField>(obj, | |
8104 HObjectAccess::ForJSObjectOffset(offset), | |
8105 Add<HConstant>(static_cast<int32_t>(0))); | |
mvstanton
2013/11/18 10:44:49
Not something we have to do now, but it would be n
Dmitry Lomov (no reviews)
2013/11/18 13:48:14
Agreed.
| |
8106 } | |
8107 | |
8108 Add<HStoreNamedField>(obj, | |
8109 HObjectAccess::ForJSObjectOffset(JSTypedArray::kBufferOffset), buffer); | |
8110 Add<HStoreNamedField>(obj, | |
8111 HObjectAccess::ForJSObjectOffset(JSTypedArray::kByteOffsetOffset), | |
8112 byte_offset); | |
8113 Add<HStoreNamedField>(obj, | |
8114 HObjectAccess::ForJSObjectOffset(JSTypedArray::kByteLengthOffset), | |
8115 byte_length); | |
8116 | |
8117 HInstruction* length = Add<HDiv>(byte_length, | |
8118 Add<HConstant>(static_cast<int32_t>(element_size))); | |
8119 | |
8120 Add<HStoreNamedField>(obj, | |
8121 HObjectAccess::ForJSObjectOffset(JSTypedArray::kLengthOffset), | |
8122 length); | |
8123 | |
8124 Add<HStoreNamedField>(obj, | |
8125 HObjectAccess::ForJSObjectOffset(JSTypedArray::kWeakNextOffset), | |
8126 Add<HLoadNamedField>(buffer, | |
8127 HObjectAccess::ForJSObjectOffset( | |
8128 | |
mvstanton
2013/11/18 10:44:49
nit: Remove newline.
Dmitry Lomov (no reviews)
2013/11/18 13:48:14
Done.
| |
8129 JSArrayBuffer::kWeakFirstViewOffset))); | |
8130 Add<HStoreNamedField>(buffer, | |
8131 HObjectAccess::ForJSObjectOffset(JSArrayBuffer::kWeakFirstViewOffset), | |
8132 obj); | |
8133 | |
8134 HValue* elements = | |
8135 Add<HAllocate>( | |
8136 Add<HConstant>(ExternalArray::kAlignedSize), | |
8137 HType::JSArray(), | |
8138 isolate()->heap()->GetPretenureMode(), | |
mvstanton
2013/11/18 10:44:49
It would be good if you continue passing NOT_TENUR
Dmitry Lomov (no reviews)
2013/11/18 13:48:14
Done.
| |
8139 static_cast<InstanceType>(FIRST_EXTERNAL_ARRAY_TYPE + array_type)); | |
8140 | |
8141 Handle<Map> external_array_map( | |
8142 isolate()->heap()->MapForExternalArrayType(array_type)); | |
8143 | |
8144 Add<HStoreNamedField>(elements, | |
8145 HObjectAccess::ForMap(), | |
8146 Add<HConstant>(external_array_map)); | |
8147 HValue* backing_store = | |
8148 Add<HLoadNamedField>(buffer, | |
8149 HObjectAccess::ForJSObjectOffset( | |
8150 JSArrayBuffer::kBackingStoreOffset, Representation::External())); | |
8151 | |
8152 HValue* typed_array_start; | |
8153 if (is_zero_byte_offset) { | |
8154 typed_array_start = backing_store; | |
8155 } else { | |
8156 HAdd* external_pointer = | |
8157 HAdd::NewExternalPointerOffset( | |
8158 zone(), graph()->GetInvalidContext(), backing_store, byte_offset); | |
8159 // Arguments are checked prior to call to TypedArrayInitialize, | |
8160 // including byte_offset. | |
8161 external_pointer->ClearFlag(HValue::kCanOverflow); | |
danno
2013/11/18 14:26:17
This should be folded into the constructor of the
Dmitry Lomov (no reviews)
2013/11/18 16:43:54
No, because it is in this particular case (in Type
| |
8162 typed_array_start = AddInstruction(external_pointer); | |
8163 } | |
8164 | |
8165 Add<HStoreNamedField>(elements, | |
8166 HObjectAccess::ForJSObjectOffset( | |
8167 ExternalArray::kExternalPointerOffset, Representation::External()), | |
8168 typed_array_start); | |
8169 Add<HStoreNamedField>(elements, | |
8170 HObjectAccess::ForJSObjectOffset(ExternalArray::kLengthOffset), | |
8171 length); | |
8172 Add<HStoreNamedField>( | |
8173 obj, HObjectAccess::ForElementsPointer(), elements); | |
8174 | |
8175 if (!is_zero_byte_offset) { | |
8176 byte_offset_smi.Else(); | |
danno
2013/11/18 14:26:17
Perhaps use the {} indenting style used in code-st
Dmitry Lomov (no reviews)
2013/11/18 16:43:54
Done.
| |
8177 Push(Add<HPushArgument>(obj)); | |
8178 VisitArgument(arguments->at(1)); | |
8179 Push(Add<HPushArgument>(buffer)); | |
8180 Push(Add<HPushArgument>(byte_offset)); | |
8181 Push(Add<HPushArgument>(byte_length)); | |
8182 Add<HCallRuntime>(expr->name(), expr->function(), 5); | |
8183 Drop(5); | |
8184 byte_offset_smi.End(); | |
8185 } | |
8186 } | |
8187 | |
8188 | |
8055 void HOptimizedGraphBuilder::VisitCallRuntime(CallRuntime* expr) { | 8189 void HOptimizedGraphBuilder::VisitCallRuntime(CallRuntime* expr) { |
8056 ASSERT(!HasStackOverflow()); | 8190 ASSERT(!HasStackOverflow()); |
8057 ASSERT(current_block() != NULL); | 8191 ASSERT(current_block() != NULL); |
8058 ASSERT(current_block()->HasPredecessor()); | 8192 ASSERT(current_block()->HasPredecessor()); |
8059 if (expr->is_jsruntime()) { | 8193 if (expr->is_jsruntime()) { |
8060 return Bailout(kCallToAJavaScriptRuntimeFunction); | 8194 return Bailout(kCallToAJavaScriptRuntimeFunction); |
8061 } | 8195 } |
8062 | 8196 |
8063 const Runtime::Function* function = expr->function(); | 8197 const Runtime::Function* function = expr->function(); |
8064 ASSERT(function != NULL); | 8198 ASSERT(function != NULL); |
8199 | |
8200 if (function->function_id == Runtime::kTypedArrayInitialize) { | |
8201 return VisitTypedArrayInitialize(expr); | |
8202 } | |
8203 | |
8204 if (function->function_id == Runtime::kMaxSmi) { | |
8205 ASSERT(expr->arguments()->length() == 0); | |
8206 HConstant* max_smi = New<HConstant>(static_cast<int32_t>(Smi::kMaxValue)); | |
8207 return ast_context()->ReturnInstruction(max_smi, expr->id()); | |
8208 } | |
8209 | |
8065 if (function->intrinsic_type == Runtime::INLINE) { | 8210 if (function->intrinsic_type == Runtime::INLINE) { |
8066 ASSERT(expr->name()->length() > 0); | 8211 ASSERT(expr->name()->length() > 0); |
8067 ASSERT(expr->name()->Get(0) == '_'); | 8212 ASSERT(expr->name()->Get(0) == '_'); |
8068 // Call to an inline function. | 8213 // Call to an inline function. |
8069 int lookup_index = static_cast<int>(function->function_id) - | 8214 int lookup_index = static_cast<int>(function->function_id) - |
8070 static_cast<int>(Runtime::kFirstInlineFunction); | 8215 static_cast<int>(Runtime::kFirstInlineFunction); |
8071 ASSERT(lookup_index >= 0); | 8216 ASSERT(lookup_index >= 0); |
8072 ASSERT(static_cast<size_t>(lookup_index) < | 8217 ASSERT(static_cast<size_t>(lookup_index) < |
8073 ARRAY_SIZE(kInlineFunctionGenerators)); | 8218 ARRAY_SIZE(kInlineFunctionGenerators)); |
8074 InlineFunctionGenerator generator = kInlineFunctionGenerators[lookup_index]; | 8219 InlineFunctionGenerator generator = kInlineFunctionGenerators[lookup_index]; |
(...skipping 2475 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
10550 if (ShouldProduceTraceOutput()) { | 10695 if (ShouldProduceTraceOutput()) { |
10551 isolate()->GetHTracer()->TraceHydrogen(name(), graph_); | 10696 isolate()->GetHTracer()->TraceHydrogen(name(), graph_); |
10552 } | 10697 } |
10553 | 10698 |
10554 #ifdef DEBUG | 10699 #ifdef DEBUG |
10555 graph_->Verify(false); // No full verify. | 10700 graph_->Verify(false); // No full verify. |
10556 #endif | 10701 #endif |
10557 } | 10702 } |
10558 | 10703 |
10559 } } // namespace v8::internal | 10704 } } // namespace v8::internal |
OLD | NEW |