yangguo@chromium.org | a6bbcc8 | 2012-12-21 12:35:02 +0000 | [diff] [blame] | 1 | // Copyright 2012 the V8 project authors. All rights reserved. |
| 2 | // Redistribution and use in source and binary forms, with or without |
| 3 | // modification, are permitted provided that the following conditions are |
| 4 | // met: |
| 5 | // |
| 6 | // * Redistributions of source code must retain the above copyright |
| 7 | // notice, this list of conditions and the following disclaimer. |
| 8 | // * Redistributions in binary form must reproduce the above |
| 9 | // copyright notice, this list of conditions and the following |
| 10 | // disclaimer in the documentation and/or other materials provided |
| 11 | // with the distribution. |
| 12 | // * Neither the name of Google Inc. nor the names of its |
| 13 | // contributors may be used to endorse or promote products derived |
| 14 | // from this software without specific prior written permission. |
| 15 | // |
| 16 | // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS |
| 17 | // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT |
| 18 | // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR |
| 19 | // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT |
| 20 | // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, |
| 21 | // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT |
| 22 | // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
| 23 | // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
| 24 | // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
| 25 | // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |
| 26 | // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
| 27 | |
| 28 | #include "v8.h" |
| 29 | |
| 30 | #include "code-stubs.h" |
| 31 | #include "hydrogen.h" |
| 32 | #include "lithium.h" |
| 33 | |
| 34 | namespace v8 { |
| 35 | namespace internal { |
| 36 | |
| 37 | |
mstarzinger@chromium.org | 068ea0a | 2013-01-30 09:39:44 +0000 | [diff] [blame] | 38 | static LChunk* OptimizeGraph(HGraph* graph) { |
ulan@chromium.org | 09d7ab5 | 2013-02-25 15:50:35 +0000 | [diff] [blame] | 39 | Isolate* isolate = graph->isolate(); |
mstarzinger@chromium.org | 068ea0a | 2013-01-30 09:39:44 +0000 | [diff] [blame] | 40 | AssertNoAllocation no_gc; |
ulan@chromium.org | 09d7ab5 | 2013-02-25 15:50:35 +0000 | [diff] [blame] | 41 | NoHandleAllocation no_handles(isolate); |
| 42 | NoHandleDereference no_deref(isolate); |
mstarzinger@chromium.org | 068ea0a | 2013-01-30 09:39:44 +0000 | [diff] [blame] | 43 | |
| 44 | ASSERT(graph != NULL); |
| 45 | SmartArrayPointer<char> bailout_reason; |
| 46 | if (!graph->Optimize(&bailout_reason)) { |
| 47 | FATAL(bailout_reason.is_empty() ? "unknown" : *bailout_reason); |
| 48 | } |
yangguo@chromium.org | a6bbcc8 | 2012-12-21 12:35:02 +0000 | [diff] [blame] | 49 | LChunk* chunk = LChunk::NewChunk(graph); |
mstarzinger@chromium.org | 068ea0a | 2013-01-30 09:39:44 +0000 | [diff] [blame] | 50 | if (chunk == NULL) { |
| 51 | FATAL(graph->info()->bailout_reason()); |
| 52 | } |
| 53 | return chunk; |
yangguo@chromium.org | a6bbcc8 | 2012-12-21 12:35:02 +0000 | [diff] [blame] | 54 | } |
| 55 | |
| 56 | |
| 57 | class CodeStubGraphBuilderBase : public HGraphBuilder { |
| 58 | public: |
| 59 | CodeStubGraphBuilderBase(Isolate* isolate, HydrogenCodeStub* stub) |
ulan@chromium.org | 09d7ab5 | 2013-02-25 15:50:35 +0000 | [diff] [blame] | 60 | : HGraphBuilder(&info_), info_(stub, isolate), context_(NULL) { |
| 61 | int major_key = stub->MajorKey(); |
| 62 | descriptor_ = info_.isolate()->code_stub_interface_descriptor(major_key); |
| 63 | if (descriptor_->register_param_count_ < 0) { |
| 64 | stub->InitializeInterfaceDescriptor(info_.isolate(), descriptor_); |
| 65 | } |
| 66 | parameters_.Reset(new HParameter*[descriptor_->register_param_count_]); |
| 67 | } |
yangguo@chromium.org | a6bbcc8 | 2012-12-21 12:35:02 +0000 | [diff] [blame] | 68 | virtual bool BuildGraph(); |
| 69 | |
| 70 | protected: |
| 71 | virtual void BuildCodeStub() = 0; |
| 72 | HParameter* GetParameter(int parameter) { return parameters_[parameter]; } |
danno@chromium.org | 94b0d6f | 2013-02-04 13:33:20 +0000 | [diff] [blame] | 73 | CompilationInfo* info() { return &info_; } |
yangguo@chromium.org | a6bbcc8 | 2012-12-21 12:35:02 +0000 | [diff] [blame] | 74 | HydrogenCodeStub* stub() { return info_.code_stub(); } |
yangguo@chromium.org | 4cd70b4 | 2013-01-04 08:57:54 +0000 | [diff] [blame] | 75 | HContext* context() { return context_; } |
danno@chromium.org | 94b0d6f | 2013-02-04 13:33:20 +0000 | [diff] [blame] | 76 | Isolate* isolate() { return info_.isolate(); } |
yangguo@chromium.org | a6bbcc8 | 2012-12-21 12:35:02 +0000 | [diff] [blame] | 77 | |
| 78 | private: |
| 79 | SmartArrayPointer<HParameter*> parameters_; |
| 80 | CompilationInfoWithZone info_; |
ulan@chromium.org | 09d7ab5 | 2013-02-25 15:50:35 +0000 | [diff] [blame] | 81 | CodeStubInterfaceDescriptor* descriptor_; |
yangguo@chromium.org | 4cd70b4 | 2013-01-04 08:57:54 +0000 | [diff] [blame] | 82 | HContext* context_; |
yangguo@chromium.org | a6bbcc8 | 2012-12-21 12:35:02 +0000 | [diff] [blame] | 83 | }; |
| 84 | |
| 85 | |
| 86 | bool CodeStubGraphBuilderBase::BuildGraph() { |
| 87 | if (FLAG_trace_hydrogen) { |
hpayer@chromium.org | 7c3372b | 2013-02-13 17:26:04 +0000 | [diff] [blame] | 88 | const char* name = CodeStub::MajorName(stub()->MajorKey(), false); |
yangguo@chromium.org | a6bbcc8 | 2012-12-21 12:35:02 +0000 | [diff] [blame] | 89 | PrintF("-----------------------------------------------------------\n"); |
hpayer@chromium.org | 7c3372b | 2013-02-13 17:26:04 +0000 | [diff] [blame] | 90 | PrintF("Compiling stub %s using hydrogen\n", name); |
yangguo@chromium.org | a6bbcc8 | 2012-12-21 12:35:02 +0000 | [diff] [blame] | 91 | HTracer::Instance()->TraceCompilation(&info_); |
| 92 | } |
ulan@chromium.org | 09d7ab5 | 2013-02-25 15:50:35 +0000 | [diff] [blame] | 93 | |
| 94 | Zone* zone = this->zone(); |
| 95 | HEnvironment* start_environment = |
| 96 | new(zone) HEnvironment(zone, descriptor_->register_param_count_); |
| 97 | HBasicBlock* next_block = CreateBasicBlock(start_environment); |
| 98 | |
| 99 | current_block()->Goto(next_block); |
| 100 | next_block->SetJoinId(BailoutId::StubEntry()); |
yangguo@chromium.org | a6bbcc8 | 2012-12-21 12:35:02 +0000 | [diff] [blame] | 101 | set_current_block(next_block); |
| 102 | |
ulan@chromium.org | 09d7ab5 | 2013-02-25 15:50:35 +0000 | [diff] [blame] | 103 | HConstant* undefined_constant = new(zone) HConstant( |
danno@chromium.org | 94b0d6f | 2013-02-04 13:33:20 +0000 | [diff] [blame] | 104 | isolate()->factory()->undefined_value(), Representation::Tagged()); |
| 105 | AddInstruction(undefined_constant); |
| 106 | graph()->set_undefined_constant(undefined_constant); |
| 107 | |
ulan@chromium.org | 09d7ab5 | 2013-02-25 15:50:35 +0000 | [diff] [blame] | 108 | int param_count = descriptor_->register_param_count_; |
| 109 | for (int i = 0; i < param_count; ++i) { |
mmassi@chromium.org | 2f0efde | 2013-02-06 14:12:58 +0000 | [diff] [blame] | 110 | HParameter* param = |
| 111 | new(zone) HParameter(i, HParameter::REGISTER_PARAMETER); |
yangguo@chromium.org | a6bbcc8 | 2012-12-21 12:35:02 +0000 | [diff] [blame] | 112 | AddInstruction(param); |
ulan@chromium.org | 09d7ab5 | 2013-02-25 15:50:35 +0000 | [diff] [blame] | 113 | start_environment->Bind(i, param); |
yangguo@chromium.org | a6bbcc8 | 2012-12-21 12:35:02 +0000 | [diff] [blame] | 114 | parameters_[i] = param; |
| 115 | } |
danno@chromium.org | 94b0d6f | 2013-02-04 13:33:20 +0000 | [diff] [blame] | 116 | |
| 117 | context_ = new(zone) HContext(); |
| 118 | AddInstruction(context_); |
ulan@chromium.org | 09d7ab5 | 2013-02-25 15:50:35 +0000 | [diff] [blame] | 119 | start_environment->Bind(param_count, context_); |
danno@chromium.org | 94b0d6f | 2013-02-04 13:33:20 +0000 | [diff] [blame] | 120 | |
yangguo@chromium.org | a6bbcc8 | 2012-12-21 12:35:02 +0000 | [diff] [blame] | 121 | AddSimulate(BailoutId::StubEntry()); |
| 122 | |
| 123 | BuildCodeStub(); |
| 124 | |
| 125 | return true; |
| 126 | } |
| 127 | |
| 128 | template <class Stub> |
| 129 | class CodeStubGraphBuilder: public CodeStubGraphBuilderBase { |
| 130 | public: |
| 131 | explicit CodeStubGraphBuilder(Stub* stub) |
| 132 | : CodeStubGraphBuilderBase(Isolate::Current(), stub) {} |
| 133 | |
| 134 | protected: |
| 135 | virtual void BuildCodeStub(); |
| 136 | Stub* casted_stub() { return static_cast<Stub*>(stub()); } |
| 137 | }; |
| 138 | |
| 139 | |
| 140 | template <> |
mstarzinger@chromium.org | 71fc346 | 2013-02-27 09:34:27 +0000 | [diff] [blame] | 141 | void CodeStubGraphBuilder<FastCloneShallowObjectStub>::BuildCodeStub() { |
| 142 | Zone* zone = this->zone(); |
| 143 | Factory* factory = isolate()->factory(); |
| 144 | |
| 145 | HInstruction* boilerplate = |
| 146 | AddInstruction(new(zone) HLoadKeyed(GetParameter(0), |
| 147 | GetParameter(1), |
| 148 | NULL, |
| 149 | FAST_ELEMENTS)); |
| 150 | |
| 151 | CheckBuilder builder(this, BailoutId::StubEntry()); |
| 152 | builder.CheckNotUndefined(boilerplate); |
| 153 | |
| 154 | int size = JSObject::kHeaderSize + casted_stub()->length() * kPointerSize; |
| 155 | HValue* boilerplate_size = |
| 156 | AddInstruction(new(zone) HInstanceSize(boilerplate)); |
| 157 | HValue* size_in_words = |
| 158 | AddInstruction(new(zone) HConstant(size >> kPointerSizeLog2, |
| 159 | Representation::Integer32())); |
| 160 | builder.CheckIntegerEq(boilerplate_size, size_in_words); |
| 161 | |
| 162 | HValue* size_in_bytes = |
| 163 | AddInstruction(new(zone) HConstant(size, Representation::Integer32())); |
| 164 | HInstruction* object = |
| 165 | AddInstruction(new(zone) HAllocate(context(), |
| 166 | size_in_bytes, |
| 167 | HType::JSObject(), |
| 168 | HAllocate::CAN_ALLOCATE_IN_NEW_SPACE)); |
| 169 | |
| 170 | for (int i = 0; i < size; i += kPointerSize) { |
| 171 | HInstruction* value = |
| 172 | AddInstruction(new(zone) HLoadNamedField(boilerplate, true, i)); |
| 173 | AddInstruction(new(zone) HStoreNamedField(object, |
yangguo@chromium.org | 4a9f655 | 2013-03-04 14:46:33 +0000 | [diff] [blame^] | 174 | factory->empty_string(), |
mstarzinger@chromium.org | 71fc346 | 2013-02-27 09:34:27 +0000 | [diff] [blame] | 175 | value, |
| 176 | true, i)); |
| 177 | AddSimulate(BailoutId::StubEntry()); |
| 178 | } |
| 179 | |
| 180 | builder.End(); |
| 181 | |
| 182 | HReturn* ret = new(zone) HReturn(object, context()); |
| 183 | current_block()->Finish(ret); |
| 184 | } |
| 185 | |
| 186 | |
| 187 | Handle<Code> FastCloneShallowObjectStub::GenerateCode() { |
| 188 | CodeStubGraphBuilder<FastCloneShallowObjectStub> builder(this); |
| 189 | LChunk* chunk = OptimizeGraph(builder.CreateGraph()); |
| 190 | return chunk->Codegen(Code::COMPILED_STUB); |
| 191 | } |
| 192 | |
| 193 | |
| 194 | template <> |
yangguo@chromium.org | a6bbcc8 | 2012-12-21 12:35:02 +0000 | [diff] [blame] | 195 | void CodeStubGraphBuilder<KeyedLoadFastElementStub>::BuildCodeStub() { |
| 196 | Zone* zone = this->zone(); |
| 197 | |
| 198 | HInstruction* load = BuildUncheckedMonomorphicElementAccess( |
| 199 | GetParameter(0), GetParameter(1), NULL, NULL, |
mstarzinger@chromium.org | 068ea0a | 2013-01-30 09:39:44 +0000 | [diff] [blame] | 200 | casted_stub()->is_js_array(), casted_stub()->elements_kind(), |
| 201 | false, Representation::Tagged()); |
yangguo@chromium.org | a6bbcc8 | 2012-12-21 12:35:02 +0000 | [diff] [blame] | 202 | AddInstruction(load); |
| 203 | |
yangguo@chromium.org | 4cd70b4 | 2013-01-04 08:57:54 +0000 | [diff] [blame] | 204 | HReturn* ret = new(zone) HReturn(load, context()); |
yangguo@chromium.org | a6bbcc8 | 2012-12-21 12:35:02 +0000 | [diff] [blame] | 205 | current_block()->Finish(ret); |
| 206 | } |
| 207 | |
| 208 | |
| 209 | Handle<Code> KeyedLoadFastElementStub::GenerateCode() { |
| 210 | CodeStubGraphBuilder<KeyedLoadFastElementStub> builder(this); |
mstarzinger@chromium.org | 068ea0a | 2013-01-30 09:39:44 +0000 | [diff] [blame] | 211 | LChunk* chunk = OptimizeGraph(builder.CreateGraph()); |
| 212 | return chunk->Codegen(Code::COMPILED_STUB); |
yangguo@chromium.org | a6bbcc8 | 2012-12-21 12:35:02 +0000 | [diff] [blame] | 213 | } |
| 214 | |
| 215 | |
danno@chromium.org | 94b0d6f | 2013-02-04 13:33:20 +0000 | [diff] [blame] | 216 | template <> |
| 217 | void CodeStubGraphBuilder<TransitionElementsKindStub>::BuildCodeStub() { |
| 218 | Zone* zone = this->zone(); |
| 219 | |
| 220 | HValue* js_array = GetParameter(0); |
| 221 | HValue* map = GetParameter(1); |
| 222 | |
| 223 | info()->MarkAsSavesCallerDoubles(); |
| 224 | |
| 225 | AddInstruction(new(zone) HTrapAllocationMemento(js_array)); |
| 226 | |
| 227 | HInstruction* array_length = |
| 228 | AddInstruction(new(zone) HJSArrayLength(js_array, |
| 229 | js_array, |
| 230 | HType::Smi())); |
| 231 | |
| 232 | Heap* heap = isolate()->heap(); |
| 233 | const int kMinFreeNewSpaceAfterGC = |
| 234 | ((heap->InitialSemiSpaceSize() - sizeof(FixedArrayBase)) / 2) / |
| 235 | kDoubleSize; |
| 236 | |
| 237 | HConstant* max_alloc_size = |
| 238 | new(zone) HConstant(kMinFreeNewSpaceAfterGC, Representation::Integer32()); |
| 239 | AddInstruction(max_alloc_size); |
hpayer@chromium.org | 7c3372b | 2013-02-13 17:26:04 +0000 | [diff] [blame] | 240 | // Since we're forcing Integer32 representation for this HBoundsCheck, |
| 241 | // there's no need to Smi-check the index. |
| 242 | AddInstruction( |
| 243 | new(zone) HBoundsCheck(array_length, max_alloc_size, |
| 244 | DONT_ALLOW_SMI_KEY, Representation::Integer32())); |
danno@chromium.org | 94b0d6f | 2013-02-04 13:33:20 +0000 | [diff] [blame] | 245 | |
mstarzinger@chromium.org | 71fc346 | 2013-02-27 09:34:27 +0000 | [diff] [blame] | 246 | IfBuilder if_builder(this, BailoutId::StubEntry()); |
danno@chromium.org | 94b0d6f | 2013-02-04 13:33:20 +0000 | [diff] [blame] | 247 | |
| 248 | if_builder.BeginTrue(array_length, graph()->GetConstant0(), Token::EQ); |
| 249 | |
| 250 | // Nothing to do, just change the map. |
| 251 | |
| 252 | if_builder.BeginFalse(); |
| 253 | |
| 254 | HInstruction* elements = |
| 255 | AddInstruction(new(zone) HLoadElements(js_array, js_array)); |
| 256 | |
| 257 | HInstruction* elements_length = |
| 258 | AddInstruction(new(zone) HFixedArrayBaseLength(elements)); |
| 259 | |
| 260 | ElementsKind to_kind = casted_stub()->to_kind(); |
| 261 | HValue* new_elements = |
| 262 | BuildAllocateElements(context(), to_kind, elements_length); |
| 263 | |
| 264 | // Fast elements kinds need to be initialized in case statements below cause a |
| 265 | // garbage collection. |
| 266 | Factory* factory = isolate()->factory(); |
| 267 | |
| 268 | ASSERT(!IsFastSmiElementsKind(to_kind)); |
| 269 | double nan_double = FixedDoubleArray::hole_nan_as_double(); |
| 270 | HValue* hole = IsFastObjectElementsKind(to_kind) |
| 271 | ? AddInstruction(new(zone) HConstant(factory->the_hole_value(), |
| 272 | Representation::Tagged())) |
| 273 | : AddInstruction(new(zone) HConstant(nan_double, |
| 274 | Representation::Double())); |
| 275 | |
mstarzinger@chromium.org | 71fc346 | 2013-02-27 09:34:27 +0000 | [diff] [blame] | 276 | LoopBuilder builder(this, context(), LoopBuilder::kPostIncrement, |
| 277 | BailoutId::StubEntry()); |
danno@chromium.org | 94b0d6f | 2013-02-04 13:33:20 +0000 | [diff] [blame] | 278 | |
| 279 | HValue* zero = graph()->GetConstant0(); |
| 280 | HValue* start = IsFastElementsKind(to_kind) ? zero : array_length; |
| 281 | HValue* key = builder.BeginBody(start, elements_length, Token::LT); |
| 282 | |
| 283 | AddInstruction(new(zone) HStoreKeyed(new_elements, key, hole, to_kind)); |
| 284 | AddSimulate(BailoutId::StubEntry(), REMOVABLE_SIMULATE); |
| 285 | |
| 286 | builder.EndBody(); |
| 287 | |
| 288 | BuildCopyElements(context(), elements, |
| 289 | casted_stub()->from_kind(), new_elements, |
| 290 | to_kind, array_length); |
| 291 | |
| 292 | AddInstruction(new(zone) HStoreNamedField(js_array, |
yangguo@chromium.org | 4a9f655 | 2013-03-04 14:46:33 +0000 | [diff] [blame^] | 293 | factory->elements_field_string(), |
danno@chromium.org | 94b0d6f | 2013-02-04 13:33:20 +0000 | [diff] [blame] | 294 | new_elements, true, |
| 295 | JSArray::kElementsOffset)); |
| 296 | AddSimulate(BailoutId::StubEntry()); |
| 297 | |
| 298 | if_builder.End(); |
| 299 | |
yangguo@chromium.org | 4a9f655 | 2013-03-04 14:46:33 +0000 | [diff] [blame^] | 300 | AddInstruction(new(zone) HStoreNamedField(js_array, factory->length_string(), |
danno@chromium.org | 94b0d6f | 2013-02-04 13:33:20 +0000 | [diff] [blame] | 301 | map, true, JSArray::kMapOffset)); |
| 302 | AddSimulate(BailoutId::StubEntry()); |
| 303 | |
| 304 | HReturn* ret = new(zone) HReturn(js_array, context()); |
| 305 | current_block()->Finish(ret); |
| 306 | } |
| 307 | |
| 308 | |
yangguo@chromium.org | 4a9f655 | 2013-03-04 14:46:33 +0000 | [diff] [blame^] | 309 | template <> |
| 310 | void CodeStubGraphBuilder<ArrayNoArgumentConstructorStub>::BuildCodeStub() { |
| 311 | HInstruction* deopt = new(zone()) HSoftDeoptimize(); |
| 312 | AddInstruction(deopt); |
| 313 | current_block()->MarkAsDeoptimizing(); |
| 314 | HReturn* ret = new(zone()) HReturn(GetParameter(0), context()); |
| 315 | current_block()->Finish(ret); |
| 316 | } |
| 317 | |
| 318 | |
| 319 | Handle<Code> ArrayNoArgumentConstructorStub::GenerateCode() { |
| 320 | CodeStubGraphBuilder<ArrayNoArgumentConstructorStub> builder(this); |
| 321 | LChunk* chunk = OptimizeGraph(builder.CreateGraph()); |
| 322 | return chunk->Codegen(Code::COMPILED_STUB); |
| 323 | } |
| 324 | |
| 325 | |
| 326 | template <> |
| 327 | void CodeStubGraphBuilder<ArraySingleArgumentConstructorStub>::BuildCodeStub() { |
| 328 | HInstruction* deopt = new(zone()) HSoftDeoptimize(); |
| 329 | AddInstruction(deopt); |
| 330 | current_block()->MarkAsDeoptimizing(); |
| 331 | HReturn* ret = new(zone()) HReturn(GetParameter(0), context()); |
| 332 | current_block()->Finish(ret); |
| 333 | } |
| 334 | |
| 335 | |
danno@chromium.org | 94b0d6f | 2013-02-04 13:33:20 +0000 | [diff] [blame] | 336 | Handle<Code> TransitionElementsKindStub::GenerateCode() { |
| 337 | CodeStubGraphBuilder<TransitionElementsKindStub> builder(this); |
| 338 | LChunk* chunk = OptimizeGraph(builder.CreateGraph()); |
| 339 | return chunk->Codegen(Code::COMPILED_STUB); |
| 340 | } |
| 341 | |
| 342 | |
yangguo@chromium.org | 4a9f655 | 2013-03-04 14:46:33 +0000 | [diff] [blame^] | 343 | Handle<Code> ArraySingleArgumentConstructorStub::GenerateCode() { |
| 344 | CodeStubGraphBuilder<ArraySingleArgumentConstructorStub> builder(this); |
| 345 | LChunk* chunk = OptimizeGraph(builder.CreateGraph()); |
| 346 | return chunk->Codegen(Code::COMPILED_STUB); |
| 347 | } |
| 348 | |
| 349 | |
| 350 | template <> |
| 351 | void CodeStubGraphBuilder<ArrayNArgumentsConstructorStub>::BuildCodeStub() { |
| 352 | HInstruction* deopt = new(zone()) HSoftDeoptimize(); |
| 353 | AddInstruction(deopt); |
| 354 | current_block()->MarkAsDeoptimizing(); |
| 355 | HReturn* ret = new(zone()) HReturn(GetParameter(0), context()); |
| 356 | current_block()->Finish(ret); |
| 357 | } |
| 358 | |
| 359 | |
| 360 | Handle<Code> ArrayNArgumentsConstructorStub::GenerateCode() { |
| 361 | CodeStubGraphBuilder<ArrayNArgumentsConstructorStub> builder(this); |
| 362 | LChunk* chunk = OptimizeGraph(builder.CreateGraph()); |
| 363 | return chunk->Codegen(Code::COMPILED_STUB); |
| 364 | } |
| 365 | |
yangguo@chromium.org | a6bbcc8 | 2012-12-21 12:35:02 +0000 | [diff] [blame] | 366 | } } // namespace v8::internal |