Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(9)

Side by Side Diff: src/code-stubs-hydrogen.cc

Issue 133443009: A64: Synchronize with r17441. (Closed) Base URL: https://v8.googlecode.com/svn/branches/experimental/a64
Patch Set: Created 6 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « src/code-stubs.cc ('k') | src/codegen.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2012 the V8 project authors. All rights reserved. 1 // Copyright 2012 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 128 matching lines...) Expand 10 before | Expand all | Expand 10 after
139 if (FLAG_trace_hydrogen_stubs) { 139 if (FLAG_trace_hydrogen_stubs) {
140 const char* name = CodeStub::MajorName(stub()->MajorKey(), false); 140 const char* name = CodeStub::MajorName(stub()->MajorKey(), false);
141 PrintF("-----------------------------------------------------------\n"); 141 PrintF("-----------------------------------------------------------\n");
142 PrintF("Compiling stub %s using hydrogen\n", name); 142 PrintF("Compiling stub %s using hydrogen\n", name);
143 isolate()->GetHTracer()->TraceCompilation(&info_); 143 isolate()->GetHTracer()->TraceCompilation(&info_);
144 } 144 }
145 145
146 int param_count = descriptor_->register_param_count_; 146 int param_count = descriptor_->register_param_count_;
147 HEnvironment* start_environment = graph()->start_environment(); 147 HEnvironment* start_environment = graph()->start_environment();
148 HBasicBlock* next_block = CreateBasicBlock(start_environment); 148 HBasicBlock* next_block = CreateBasicBlock(start_environment);
149 current_block()->Goto(next_block); 149 Goto(next_block);
150 next_block->SetJoinId(BailoutId::StubEntry()); 150 next_block->SetJoinId(BailoutId::StubEntry());
151 set_current_block(next_block); 151 set_current_block(next_block);
152 152
153 HConstant* undefined_constant =
154 Add<HConstant>(isolate()->factory()->undefined_value());
155 graph()->set_undefined_constant(undefined_constant);
156
157 for (int i = 0; i < param_count; ++i) { 153 for (int i = 0; i < param_count; ++i) {
158 HParameter* param = 154 HParameter* param =
159 Add<HParameter>(i, HParameter::REGISTER_PARAMETER); 155 Add<HParameter>(i, HParameter::REGISTER_PARAMETER);
160 start_environment->Bind(i, param); 156 start_environment->Bind(i, param);
161 parameters_[i] = param; 157 parameters_[i] = param;
162 } 158 }
163 159
164 HInstruction* stack_parameter_count; 160 HInstruction* stack_parameter_count;
165 if (descriptor_->stack_parameter_count_ != NULL) { 161 if (descriptor_->stack_parameter_count_.is_valid()) {
166 ASSERT(descriptor_->environment_length() == (param_count + 1)); 162 ASSERT(descriptor_->environment_length() == (param_count + 1));
167 stack_parameter_count = New<HParameter>(param_count, 163 stack_parameter_count = New<HParameter>(param_count,
168 HParameter::REGISTER_PARAMETER, 164 HParameter::REGISTER_PARAMETER,
169 Representation::Integer32()); 165 Representation::Integer32());
170 stack_parameter_count->set_type(HType::Smi()); 166 stack_parameter_count->set_type(HType::Smi());
171 // It's essential to bind this value to the environment in case of deopt. 167 // It's essential to bind this value to the environment in case of deopt.
172 AddInstruction(stack_parameter_count); 168 AddInstruction(stack_parameter_count);
173 start_environment->Bind(param_count, stack_parameter_count); 169 start_environment->Bind(param_count, stack_parameter_count);
174 arguments_length_ = stack_parameter_count; 170 arguments_length_ = stack_parameter_count;
175 } else { 171 } else {
176 ASSERT(descriptor_->environment_length() == param_count); 172 ASSERT(descriptor_->environment_length() == param_count);
177 stack_parameter_count = graph()->GetConstantMinus1(); 173 stack_parameter_count = graph()->GetConstantMinus1();
178 arguments_length_ = graph()->GetConstant0(); 174 arguments_length_ = graph()->GetConstant0();
179 } 175 }
180 176
181 context_ = New<HContext>(); 177 context_ = Add<HContext>();
182 AddInstruction(context_);
183 start_environment->BindContext(context_); 178 start_environment->BindContext(context_);
184 179
185 Add<HSimulate>(BailoutId::StubEntry()); 180 Add<HSimulate>(BailoutId::StubEntry());
186 181
187 NoObservableSideEffectsScope no_effects(this); 182 NoObservableSideEffectsScope no_effects(this);
188 183
189 HValue* return_value = BuildCodeStub(); 184 HValue* return_value = BuildCodeStub();
190 185
191 // We might have extra expressions to pop from the stack in addition to the 186 // We might have extra expressions to pop from the stack in addition to the
192 // arguments above. 187 // arguments above.
193 HInstruction* stack_pop_count = stack_parameter_count; 188 HInstruction* stack_pop_count = stack_parameter_count;
194 if (descriptor_->function_mode_ == JS_FUNCTION_STUB_MODE) { 189 if (descriptor_->function_mode_ == JS_FUNCTION_STUB_MODE) {
195 if (!stack_parameter_count->IsConstant() && 190 if (!stack_parameter_count->IsConstant() &&
196 descriptor_->hint_stack_parameter_count_ < 0) { 191 descriptor_->hint_stack_parameter_count_ < 0) {
197 HInstruction* amount = graph()->GetConstant1(); 192 HInstruction* amount = graph()->GetConstant1();
198 stack_pop_count = Add<HAdd>(stack_parameter_count, amount); 193 stack_pop_count = Add<HAdd>(stack_parameter_count, amount);
199 stack_pop_count->ChangeRepresentation(Representation::Integer32()); 194 stack_pop_count->ChangeRepresentation(Representation::Integer32());
200 stack_pop_count->ClearFlag(HValue::kCanOverflow); 195 stack_pop_count->ClearFlag(HValue::kCanOverflow);
201 } else { 196 } else {
202 int count = descriptor_->hint_stack_parameter_count_; 197 int count = descriptor_->hint_stack_parameter_count_;
203 stack_pop_count = Add<HConstant>(count); 198 stack_pop_count = Add<HConstant>(count);
204 } 199 }
205 } 200 }
206 201
207 if (current_block() != NULL) { 202 if (current_block() != NULL) {
208 HReturn* hreturn_instruction = New<HReturn>(return_value, 203 HReturn* hreturn_instruction = New<HReturn>(return_value,
209 stack_pop_count); 204 stack_pop_count);
210 current_block()->Finish(hreturn_instruction); 205 FinishCurrentBlock(hreturn_instruction);
211 set_current_block(NULL);
212 } 206 }
213 return true; 207 return true;
214 } 208 }
215 209
216 210
217 template <class Stub> 211 template <class Stub>
218 class CodeStubGraphBuilder: public CodeStubGraphBuilderBase { 212 class CodeStubGraphBuilder: public CodeStubGraphBuilderBase {
219 public: 213 public:
220 explicit CodeStubGraphBuilder(Isolate* isolate, Stub* stub) 214 explicit CodeStubGraphBuilder(Isolate* isolate, Stub* stub)
221 : CodeStubGraphBuilderBase(isolate, stub) {} 215 : CodeStubGraphBuilderBase(isolate, stub) {}
(...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after
291 CodeStubInterfaceDescriptor* descriptor = 285 CodeStubInterfaceDescriptor* descriptor =
292 isolate->code_stub_interface_descriptor(major_key); 286 isolate->code_stub_interface_descriptor(major_key);
293 if (descriptor->register_param_count_ < 0) { 287 if (descriptor->register_param_count_ < 0) {
294 stub->InitializeInterfaceDescriptor(isolate, descriptor); 288 stub->InitializeInterfaceDescriptor(isolate, descriptor);
295 } 289 }
296 290
297 // If we are uninitialized we can use a light-weight stub to enter 291 // If we are uninitialized we can use a light-weight stub to enter
298 // the runtime that is significantly faster than using the standard 292 // the runtime that is significantly faster than using the standard
299 // stub-failure deopt mechanism. 293 // stub-failure deopt mechanism.
300 if (stub->IsUninitialized() && descriptor->has_miss_handler()) { 294 if (stub->IsUninitialized() && descriptor->has_miss_handler()) {
301 ASSERT(descriptor->stack_parameter_count_ == NULL); 295 ASSERT(!descriptor->stack_parameter_count_.is_valid());
302 return stub->GenerateLightweightMissCode(isolate); 296 return stub->GenerateLightweightMissCode(isolate);
303 } 297 }
304 ElapsedTimer timer; 298 ElapsedTimer timer;
305 if (FLAG_profile_hydrogen_code_stub_compilation) { 299 if (FLAG_profile_hydrogen_code_stub_compilation) {
306 timer.Start(); 300 timer.Start();
307 } 301 }
308 CodeStubGraphBuilder<Stub> builder(isolate, stub); 302 CodeStubGraphBuilder<Stub> builder(isolate, stub);
309 LChunk* chunk = OptimizeGraph(builder.CreateGraph()); 303 LChunk* chunk = OptimizeGraph(builder.CreateGraph());
310 Handle<Code> code = chunk->Codegen(); 304 Handle<Code> code = chunk->Codegen();
311 if (FLAG_profile_hydrogen_code_stub_compilation) { 305 if (FLAG_profile_hydrogen_code_stub_compilation) {
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after
344 338
345 Handle<Code> ToNumberStub::GenerateCode(Isolate* isolate) { 339 Handle<Code> ToNumberStub::GenerateCode(Isolate* isolate) {
346 return DoGenerateCode(isolate, this); 340 return DoGenerateCode(isolate, this);
347 } 341 }
348 342
349 343
350 template <> 344 template <>
351 HValue* CodeStubGraphBuilder<NumberToStringStub>::BuildCodeStub() { 345 HValue* CodeStubGraphBuilder<NumberToStringStub>::BuildCodeStub() {
352 info()->MarkAsSavesCallerDoubles(); 346 info()->MarkAsSavesCallerDoubles();
353 HValue* number = GetParameter(NumberToStringStub::kNumber); 347 HValue* number = GetParameter(NumberToStringStub::kNumber);
354 return BuildNumberToString(number); 348 return BuildNumberToString(number, handle(Type::Number(), isolate()));
355 } 349 }
356 350
357 351
358 Handle<Code> NumberToStringStub::GenerateCode(Isolate* isolate) { 352 Handle<Code> NumberToStringStub::GenerateCode(Isolate* isolate) {
359 return DoGenerateCode(isolate, this); 353 return DoGenerateCode(isolate, this);
360 } 354 }
361 355
362 356
363 template <> 357 template <>
364 HValue* CodeStubGraphBuilder<FastCloneShallowArrayStub>::BuildCodeStub() { 358 HValue* CodeStubGraphBuilder<FastCloneShallowArrayStub>::BuildCodeStub() {
365 Factory* factory = isolate()->factory(); 359 Factory* factory = isolate()->factory();
366 HValue* undefined = graph()->GetConstantUndefined(); 360 HValue* undefined = graph()->GetConstantUndefined();
367 AllocationSiteMode alloc_site_mode = casted_stub()->allocation_site_mode(); 361 AllocationSiteMode alloc_site_mode = casted_stub()->allocation_site_mode();
368 FastCloneShallowArrayStub::Mode mode = casted_stub()->mode(); 362 FastCloneShallowArrayStub::Mode mode = casted_stub()->mode();
369 int length = casted_stub()->length(); 363 int length = casted_stub()->length();
370 364
371 HInstruction* allocation_site = Add<HLoadKeyed>(GetParameter(0), 365 HInstruction* allocation_site = Add<HLoadKeyed>(GetParameter(0),
372 GetParameter(1), 366 GetParameter(1),
373 static_cast<HValue*>(NULL), 367 static_cast<HValue*>(NULL),
374 FAST_ELEMENTS); 368 FAST_ELEMENTS);
375 IfBuilder checker(this); 369 IfBuilder checker(this);
376 checker.IfNot<HCompareObjectEqAndBranch, HValue*>(allocation_site, 370 checker.IfNot<HCompareObjectEqAndBranch, HValue*>(allocation_site,
377 undefined); 371 undefined);
378 checker.Then(); 372 checker.Then();
379 373
380 HObjectAccess access = HObjectAccess::ForAllocationSiteTransitionInfo(); 374 HObjectAccess access = HObjectAccess::ForAllocationSiteOffset(
375 AllocationSite::kTransitionInfoOffset);
381 HInstruction* boilerplate = Add<HLoadNamedField>(allocation_site, access); 376 HInstruction* boilerplate = Add<HLoadNamedField>(allocation_site, access);
382 HValue* push_value; 377 HValue* push_value;
383 if (mode == FastCloneShallowArrayStub::CLONE_ANY_ELEMENTS) { 378 if (mode == FastCloneShallowArrayStub::CLONE_ANY_ELEMENTS) {
384 HValue* elements = AddLoadElements(boilerplate); 379 HValue* elements = AddLoadElements(boilerplate);
385 380
386 IfBuilder if_fixed_cow(this); 381 IfBuilder if_fixed_cow(this);
387 if_fixed_cow.If<HCompareMap>(elements, factory->fixed_cow_array_map()); 382 if_fixed_cow.If<HCompareMap>(elements, factory->fixed_cow_array_map());
388 if_fixed_cow.Then(); 383 if_fixed_cow.Then();
389 push_value = BuildCloneShallowArray(boilerplate, 384 push_value = BuildCloneShallowArray(boilerplate,
390 allocation_site, 385 allocation_site,
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after
427 } 422 }
428 423
429 424
430 Handle<Code> FastCloneShallowArrayStub::GenerateCode(Isolate* isolate) { 425 Handle<Code> FastCloneShallowArrayStub::GenerateCode(Isolate* isolate) {
431 return DoGenerateCode(isolate, this); 426 return DoGenerateCode(isolate, this);
432 } 427 }
433 428
434 429
435 template <> 430 template <>
436 HValue* CodeStubGraphBuilder<FastCloneShallowObjectStub>::BuildCodeStub() { 431 HValue* CodeStubGraphBuilder<FastCloneShallowObjectStub>::BuildCodeStub() {
437 Zone* zone = this->zone();
438 HValue* undefined = graph()->GetConstantUndefined(); 432 HValue* undefined = graph()->GetConstantUndefined();
439 433
440 HInstruction* boilerplate = Add<HLoadKeyed>(GetParameter(0), 434 HInstruction* allocation_site = Add<HLoadKeyed>(GetParameter(0),
441 GetParameter(1), 435 GetParameter(1),
442 static_cast<HValue*>(NULL), 436 static_cast<HValue*>(NULL),
443 FAST_ELEMENTS); 437 FAST_ELEMENTS);
444 438
445 IfBuilder checker(this); 439 IfBuilder checker(this);
446 checker.IfNot<HCompareObjectEqAndBranch, HValue*>(boilerplate, 440 checker.IfNot<HCompareObjectEqAndBranch, HValue*>(allocation_site,
447 undefined); 441 undefined);
448 checker.And(); 442 checker.And();
449 443
444 HObjectAccess access = HObjectAccess::ForAllocationSiteOffset(
445 AllocationSite::kTransitionInfoOffset);
446 HInstruction* boilerplate = Add<HLoadNamedField>(allocation_site, access);
447
450 int size = JSObject::kHeaderSize + casted_stub()->length() * kPointerSize; 448 int size = JSObject::kHeaderSize + casted_stub()->length() * kPointerSize;
451 HValue* boilerplate_size = 449 int object_size = size;
452 AddInstruction(new(zone) HInstanceSize(boilerplate)); 450 if (FLAG_allocation_site_pretenuring) {
453 HValue* size_in_words = Add<HConstant>(size >> kPointerSizeLog2); 451 size += AllocationMemento::kSize;
452 }
453
454 HValue* boilerplate_map = Add<HLoadNamedField>(
455 boilerplate, HObjectAccess::ForMap());
456 HValue* boilerplate_size = Add<HLoadNamedField>(
457 boilerplate_map, HObjectAccess::ForMapInstanceSize());
458 HValue* size_in_words = Add<HConstant>(object_size >> kPointerSizeLog2);
454 checker.If<HCompareNumericAndBranch>(boilerplate_size, 459 checker.If<HCompareNumericAndBranch>(boilerplate_size,
455 size_in_words, Token::EQ); 460 size_in_words, Token::EQ);
456 checker.Then(); 461 checker.Then();
457 462
458 HValue* size_in_bytes = Add<HConstant>(size); 463 HValue* size_in_bytes = Add<HConstant>(size);
459 464
460 HInstruction* object = Add<HAllocate>(size_in_bytes, HType::JSObject(), 465 HInstruction* object = Add<HAllocate>(size_in_bytes, HType::JSObject(),
461 isolate()->heap()->GetPretenureMode(), JS_OBJECT_TYPE); 466 isolate()->heap()->GetPretenureMode(), JS_OBJECT_TYPE);
462 467
463 for (int i = 0; i < size; i += kPointerSize) { 468 for (int i = 0; i < object_size; i += kPointerSize) {
464 HObjectAccess access = HObjectAccess::ForJSObjectOffset(i); 469 HObjectAccess access = HObjectAccess::ForJSObjectOffset(i);
465 Add<HStoreNamedField>(object, access, 470 Add<HStoreNamedField>(object, access,
466 Add<HLoadNamedField>(boilerplate, access)); 471 Add<HLoadNamedField>(boilerplate, access));
467 } 472 }
468 473
474 ASSERT(FLAG_allocation_site_pretenuring || (size == object_size));
475 if (FLAG_allocation_site_pretenuring) {
476 BuildCreateAllocationMemento(object, object_size, allocation_site);
477 }
478
469 environment()->Push(object); 479 environment()->Push(object);
470 checker.ElseDeopt("Uninitialized boilerplate in fast clone"); 480 checker.ElseDeopt("Uninitialized boilerplate in fast clone");
471 checker.End(); 481 checker.End();
472 482
473 return environment()->Pop(); 483 return environment()->Pop();
474 } 484 }
475 485
476 486
477 Handle<Code> FastCloneShallowObjectStub::GenerateCode(Isolate* isolate) { 487 Handle<Code> FastCloneShallowObjectStub::GenerateCode(Isolate* isolate) {
478 return DoGenerateCode(isolate, this); 488 return DoGenerateCode(isolate, this);
479 } 489 }
480 490
481 491
482 template <> 492 template <>
483 HValue* CodeStubGraphBuilder<CreateAllocationSiteStub>::BuildCodeStub() { 493 HValue* CodeStubGraphBuilder<CreateAllocationSiteStub>::BuildCodeStub() {
484 HValue* size = Add<HConstant>(AllocationSite::kSize); 494 HValue* size = Add<HConstant>(AllocationSite::kSize);
485 HInstruction* object = Add<HAllocate>(size, HType::JSObject(), TENURED, 495 HInstruction* object = Add<HAllocate>(size, HType::JSObject(), TENURED,
486 JS_OBJECT_TYPE); 496 JS_OBJECT_TYPE);
487 497
488 // Store the map 498 // Store the map
489 Handle<Map> allocation_site_map = isolate()->factory()->allocation_site_map(); 499 Handle<Map> allocation_site_map = isolate()->factory()->allocation_site_map();
490 AddStoreMapConstant(object, allocation_site_map); 500 AddStoreMapConstant(object, allocation_site_map);
491 501
492 // Store the payload (smi elements kind) 502 // Store the payload (smi elements kind)
493 HValue* initial_elements_kind = Add<HConstant>(GetInitialFastElementsKind()); 503 HValue* initial_elements_kind = Add<HConstant>(GetInitialFastElementsKind());
494 Add<HStoreNamedField>(object, 504 Add<HStoreNamedField>(object,
495 HObjectAccess::ForAllocationSiteTransitionInfo(), 505 HObjectAccess::ForAllocationSiteOffset(
506 AllocationSite::kTransitionInfoOffset),
496 initial_elements_kind); 507 initial_elements_kind);
497 508
498 // Unlike literals, constructed arrays don't have nested sites 509 // Unlike literals, constructed arrays don't have nested sites
499 Add<HStoreNamedField>(object, 510 Add<HStoreNamedField>(object,
500 HObjectAccess::ForAllocationSiteNestedSite(), 511 HObjectAccess::ForAllocationSiteOffset(
512 AllocationSite::kNestedSiteOffset),
501 graph()->GetConstant0()); 513 graph()->GetConstant0());
502 514
503 // Store an empty fixed array for the code dependency. 515 // Store an empty fixed array for the code dependency.
504 HConstant* empty_fixed_array = 516 HConstant* empty_fixed_array =
505 Add<HConstant>(isolate()->factory()->empty_fixed_array()); 517 Add<HConstant>(isolate()->factory()->empty_fixed_array());
506 HStoreNamedField* store = Add<HStoreNamedField>( 518 HStoreNamedField* store = Add<HStoreNamedField>(
507 object, 519 object,
508 HObjectAccess::ForAllocationSiteDependentCode(), 520 HObjectAccess::ForAllocationSiteOffset(
521 AllocationSite::kDependentCodeOffset),
509 empty_fixed_array); 522 empty_fixed_array);
510 523
511 // Link the object to the allocation site list 524 // Link the object to the allocation site list
512 HValue* site_list = Add<HConstant>( 525 HValue* site_list = Add<HConstant>(
513 ExternalReference::allocation_sites_list_address(isolate())); 526 ExternalReference::allocation_sites_list_address(isolate()));
514 HValue* site = Add<HLoadNamedField>(site_list, 527 HValue* site = Add<HLoadNamedField>(site_list,
515 HObjectAccess::ForAllocationSiteList()); 528 HObjectAccess::ForAllocationSiteList());
516 store = Add<HStoreNamedField>(object, 529 store = Add<HStoreNamedField>(object,
517 HObjectAccess::ForAllocationSiteWeakNext(), 530 HObjectAccess::ForAllocationSiteOffset(AllocationSite::kWeakNextOffset),
518 site); 531 site);
519 store->SkipWriteBarrier(); 532 store->SkipWriteBarrier();
520 Add<HStoreNamedField>(site_list, HObjectAccess::ForAllocationSiteList(), 533 Add<HStoreNamedField>(site_list, HObjectAccess::ForAllocationSiteList(),
521 object); 534 object);
522 535
523 // We use a hammer (SkipWriteBarrier()) to indicate that we know the input 536 // We use a hammer (SkipWriteBarrier()) to indicate that we know the input
524 // cell is really a Cell, and so no write barrier is needed. 537 // cell is really a Cell, and so no write barrier is needed.
525 // TODO(mvstanton): Add a debug_code check to verify the input cell is really 538 // TODO(mvstanton): Add a debug_code check to verify the input cell is really
526 // a cell. (perhaps with a new instruction, HAssert). 539 // a cell. (perhaps with a new instruction, HAssert).
527 HInstruction* cell = GetParameter(0); 540 HInstruction* cell = GetParameter(0);
528 HObjectAccess access = HObjectAccess::ForCellValue(); 541 HObjectAccess access = HObjectAccess::ForCellValue();
(...skipping 22 matching lines...) Expand all
551 return DoGenerateCode(isolate, this); 564 return DoGenerateCode(isolate, this);
552 } 565 }
553 566
554 567
555 template<> 568 template<>
556 HValue* CodeStubGraphBuilder<LoadFieldStub>::BuildCodeStub() { 569 HValue* CodeStubGraphBuilder<LoadFieldStub>::BuildCodeStub() {
557 Representation rep = casted_stub()->representation(); 570 Representation rep = casted_stub()->representation();
558 HObjectAccess access = casted_stub()->is_inobject() ? 571 HObjectAccess access = casted_stub()->is_inobject() ?
559 HObjectAccess::ForJSObjectOffset(casted_stub()->offset(), rep) : 572 HObjectAccess::ForJSObjectOffset(casted_stub()->offset(), rep) :
560 HObjectAccess::ForBackingStoreOffset(casted_stub()->offset(), rep); 573 HObjectAccess::ForBackingStoreOffset(casted_stub()->offset(), rep);
561 return AddInstruction(BuildLoadNamedField(GetParameter(0), access)); 574 return AddLoadNamedField(GetParameter(0), access);
562 } 575 }
563 576
564 577
565 Handle<Code> LoadFieldStub::GenerateCode(Isolate* isolate) { 578 Handle<Code> LoadFieldStub::GenerateCode(Isolate* isolate) {
566 return DoGenerateCode(isolate, this); 579 return DoGenerateCode(isolate, this);
567 } 580 }
568 581
569 582
570 template<> 583 template<>
571 HValue* CodeStubGraphBuilder<KeyedLoadFieldStub>::BuildCodeStub() { 584 HValue* CodeStubGraphBuilder<KeyedLoadFieldStub>::BuildCodeStub() {
572 Representation rep = casted_stub()->representation(); 585 Representation rep = casted_stub()->representation();
573 HObjectAccess access = casted_stub()->is_inobject() ? 586 HObjectAccess access = casted_stub()->is_inobject() ?
574 HObjectAccess::ForJSObjectOffset(casted_stub()->offset(), rep) : 587 HObjectAccess::ForJSObjectOffset(casted_stub()->offset(), rep) :
575 HObjectAccess::ForBackingStoreOffset(casted_stub()->offset(), rep); 588 HObjectAccess::ForBackingStoreOffset(casted_stub()->offset(), rep);
576 return AddInstruction(BuildLoadNamedField(GetParameter(0), access)); 589 return AddLoadNamedField(GetParameter(0), access);
577 } 590 }
578 591
579 592
580 Handle<Code> KeyedLoadFieldStub::GenerateCode(Isolate* isolate) { 593 Handle<Code> KeyedLoadFieldStub::GenerateCode(Isolate* isolate) {
581 return DoGenerateCode(isolate, this); 594 return DoGenerateCode(isolate, this);
582 } 595 }
583 596
584 597
585 template <> 598 template <>
586 HValue* CodeStubGraphBuilder<KeyedStoreFastElementStub>::BuildCodeStub() { 599 HValue* CodeStubGraphBuilder<KeyedStoreFastElementStub>::BuildCodeStub() {
(...skipping 85 matching lines...) Expand 10 before | Expand all | Expand 10 after
672 } 685 }
673 686
674 687
675 HValue* CodeStubGraphBuilderBase::BuildArraySingleArgumentConstructor( 688 HValue* CodeStubGraphBuilderBase::BuildArraySingleArgumentConstructor(
676 JSArrayBuilder* array_builder) { 689 JSArrayBuilder* array_builder) {
677 // Smi check and range check on the input arg. 690 // Smi check and range check on the input arg.
678 HValue* constant_one = graph()->GetConstant1(); 691 HValue* constant_one = graph()->GetConstant1();
679 HValue* constant_zero = graph()->GetConstant0(); 692 HValue* constant_zero = graph()->GetConstant0();
680 693
681 HInstruction* elements = Add<HArgumentsElements>(false); 694 HInstruction* elements = Add<HArgumentsElements>(false);
682 HInstruction* argument = AddInstruction( 695 HInstruction* argument = Add<HAccessArgumentsAt>(
683 new(zone()) HAccessArgumentsAt(elements, constant_one, constant_zero)); 696 elements, constant_one, constant_zero);
684 697
685 HConstant* max_alloc_length = 698 HConstant* max_alloc_length =
686 Add<HConstant>(JSObject::kInitialMaxFastElementArray); 699 Add<HConstant>(JSObject::kInitialMaxFastElementArray);
687 const int initial_capacity = JSArray::kPreallocatedArrayElements; 700 const int initial_capacity = JSArray::kPreallocatedArrayElements;
688 HConstant* initial_capacity_node = New<HConstant>(initial_capacity); 701 HConstant* initial_capacity_node = Add<HConstant>(initial_capacity);
689 AddInstruction(initial_capacity_node);
690 702
691 HInstruction* checked_arg = Add<HBoundsCheck>(argument, max_alloc_length); 703 HInstruction* checked_arg = Add<HBoundsCheck>(argument, max_alloc_length);
692 IfBuilder if_builder(this); 704 IfBuilder if_builder(this);
693 if_builder.If<HCompareNumericAndBranch>(checked_arg, constant_zero, 705 if_builder.If<HCompareNumericAndBranch>(checked_arg, constant_zero,
694 Token::EQ); 706 Token::EQ);
695 if_builder.Then(); 707 if_builder.Then();
696 Push(initial_capacity_node); // capacity 708 Push(initial_capacity_node); // capacity
697 Push(constant_zero); // length 709 Push(constant_zero); // length
698 if_builder.Else(); 710 if_builder.Else();
699 Push(checked_arg); // capacity 711 Push(checked_arg); // capacity
(...skipping 22 matching lines...) Expand all
722 HValue* elements = array_builder->GetElementsLocation(); 734 HValue* elements = array_builder->GetElementsLocation();
723 ASSERT(elements != NULL); 735 ASSERT(elements != NULL);
724 736
725 // Now populate the elements correctly. 737 // Now populate the elements correctly.
726 LoopBuilder builder(this, 738 LoopBuilder builder(this,
727 context(), 739 context(),
728 LoopBuilder::kPostIncrement); 740 LoopBuilder::kPostIncrement);
729 HValue* start = graph()->GetConstant0(); 741 HValue* start = graph()->GetConstant0();
730 HValue* key = builder.BeginBody(start, length, Token::LT); 742 HValue* key = builder.BeginBody(start, length, Token::LT);
731 HInstruction* argument_elements = Add<HArgumentsElements>(false); 743 HInstruction* argument_elements = Add<HArgumentsElements>(false);
732 HInstruction* argument = AddInstruction(new(zone()) HAccessArgumentsAt( 744 HInstruction* argument = Add<HAccessArgumentsAt>(
733 argument_elements, length, key)); 745 argument_elements, length, key);
734 746
735 Add<HStoreKeyed>(elements, key, argument, kind); 747 Add<HStoreKeyed>(elements, key, argument, kind);
736 builder.EndBody(); 748 builder.EndBody();
737 return new_object; 749 return new_object;
738 } 750 }
739 751
740 752
741 template <> 753 template <>
742 HValue* CodeStubGraphBuilder<ArrayNoArgumentConstructorStub>::BuildCodeStub() { 754 HValue* CodeStubGraphBuilder<ArrayNoArgumentConstructorStub>::BuildCodeStub() {
743 ElementsKind kind = casted_stub()->elements_kind(); 755 ElementsKind kind = casted_stub()->elements_kind();
(...skipping 80 matching lines...) Expand 10 before | Expand all | Expand 10 after
824 } 836 }
825 837
826 838
827 template <> 839 template <>
828 HValue* CodeStubGraphBuilder<CompareNilICStub>::BuildCodeInitializedStub() { 840 HValue* CodeStubGraphBuilder<CompareNilICStub>::BuildCodeInitializedStub() {
829 Isolate* isolate = graph()->isolate(); 841 Isolate* isolate = graph()->isolate();
830 CompareNilICStub* stub = casted_stub(); 842 CompareNilICStub* stub = casted_stub();
831 HIfContinuation continuation; 843 HIfContinuation continuation;
832 Handle<Map> sentinel_map(isolate->heap()->meta_map()); 844 Handle<Map> sentinel_map(isolate->heap()->meta_map());
833 Handle<Type> type = stub->GetType(isolate, sentinel_map); 845 Handle<Type> type = stub->GetType(isolate, sentinel_map);
834 BuildCompareNil(GetParameter(0), type, RelocInfo::kNoPosition, &continuation); 846 BuildCompareNil(GetParameter(0), type, &continuation);
835 IfBuilder if_nil(this, &continuation); 847 IfBuilder if_nil(this, &continuation);
836 if_nil.Then(); 848 if_nil.Then();
837 if (continuation.IsFalseReachable()) { 849 if (continuation.IsFalseReachable()) {
838 if_nil.Else(); 850 if_nil.Else();
839 if_nil.Return(graph()->GetConstant0()); 851 if_nil.Return(graph()->GetConstant0());
840 } 852 }
841 if_nil.End(); 853 if_nil.End();
842 return continuation.IsTrueReachable() 854 return continuation.IsTrueReachable()
843 ? graph()->GetConstant1() 855 ? graph()->GetConstant1()
844 : graph()->GetConstantUndefined(); 856 : graph()->GetConstantUndefined();
(...skipping 15 matching lines...) Expand all
860 Handle<Type> right_type = stub->GetRightType(isolate()); 872 Handle<Type> right_type = stub->GetRightType(isolate());
861 Handle<Type> result_type = stub->GetResultType(isolate()); 873 Handle<Type> result_type = stub->GetResultType(isolate());
862 874
863 ASSERT(!left_type->Is(Type::None()) && !right_type->Is(Type::None()) && 875 ASSERT(!left_type->Is(Type::None()) && !right_type->Is(Type::None()) &&
864 (stub->HasSideEffects(isolate()) || !result_type->Is(Type::None()))); 876 (stub->HasSideEffects(isolate()) || !result_type->Is(Type::None())));
865 877
866 HValue* result = NULL; 878 HValue* result = NULL;
867 if (stub->operation() == Token::ADD && 879 if (stub->operation() == Token::ADD &&
868 (left_type->Maybe(Type::String()) || right_type->Maybe(Type::String())) && 880 (left_type->Maybe(Type::String()) || right_type->Maybe(Type::String())) &&
869 !left_type->Is(Type::String()) && !right_type->Is(Type::String())) { 881 !left_type->Is(Type::String()) && !right_type->Is(Type::String())) {
870 // For the generic add stub a fast case for String add is performance 882 // For the generic add stub a fast case for string addition is performance
871 // critical. 883 // critical.
872 if (left_type->Maybe(Type::String())) { 884 if (left_type->Maybe(Type::String())) {
873 IfBuilder left_string(this); 885 IfBuilder if_leftisstring(this);
874 left_string.IfNot<HIsSmiAndBranch>(left); 886 if_leftisstring.If<HIsStringAndBranch>(left);
875 left_string.AndIf<HIsStringAndBranch>(left); 887 if_leftisstring.Then();
876 left_string.Then(); 888 {
877 Push(Add<HStringAdd>(left, right, STRING_ADD_CHECK_RIGHT)); 889 Push(AddInstruction(BuildBinaryOperation(
878 left_string.Else(); 890 stub->operation(), left, right,
879 Push(AddInstruction(BuildBinaryOperation(stub->operation(), 891 handle(Type::String(), isolate()), right_type,
880 left, right, left_type, right_type, result_type, 892 result_type, stub->fixed_right_arg(), true)));
881 stub->fixed_right_arg(), true))); 893 }
882 left_string.End(); 894 if_leftisstring.Else();
895 {
896 Push(AddInstruction(BuildBinaryOperation(
897 stub->operation(), left, right,
898 left_type, right_type, result_type,
899 stub->fixed_right_arg(), true)));
900 }
901 if_leftisstring.End();
883 result = Pop(); 902 result = Pop();
884 } else { 903 } else {
885 IfBuilder right_string(this); 904 IfBuilder if_rightisstring(this);
886 right_string.IfNot<HIsSmiAndBranch>(right); 905 if_rightisstring.If<HIsStringAndBranch>(right);
887 right_string.AndIf<HIsStringAndBranch>(right); 906 if_rightisstring.Then();
888 right_string.Then(); 907 {
889 Push(Add<HStringAdd>(left, right, STRING_ADD_CHECK_LEFT)); 908 Push(AddInstruction(BuildBinaryOperation(
890 right_string.Else(); 909 stub->operation(), left, right,
891 Push(AddInstruction(BuildBinaryOperation(stub->operation(), 910 left_type, handle(Type::String(), isolate()),
892 left, right, left_type, right_type, result_type, 911 result_type, stub->fixed_right_arg(), true)));
893 stub->fixed_right_arg(), true))); 912 }
894 right_string.End(); 913 if_rightisstring.Else();
914 {
915 Push(AddInstruction(BuildBinaryOperation(
916 stub->operation(), left, right,
917 left_type, right_type, result_type,
918 stub->fixed_right_arg(), true)));
919 }
920 if_rightisstring.End();
895 result = Pop(); 921 result = Pop();
896 } 922 }
897 } else { 923 } else {
898 result = AddInstruction(BuildBinaryOperation(stub->operation(), 924 result = AddInstruction(BuildBinaryOperation(
899 left, right, left_type, right_type, result_type, 925 stub->operation(), left, right,
900 stub->fixed_right_arg(), true)); 926 left_type, right_type, result_type,
927 stub->fixed_right_arg(), true));
901 } 928 }
902 929
903 // If we encounter a generic argument, the number conversion is 930 // If we encounter a generic argument, the number conversion is
904 // observable, thus we cannot afford to bail out after the fact. 931 // observable, thus we cannot afford to bail out after the fact.
905 if (!stub->HasSideEffects(isolate())) { 932 if (!stub->HasSideEffects(isolate())) {
906 if (result_type->Is(Type::Smi())) { 933 if (result_type->Is(Type::Smi())) {
907 if (stub->operation() == Token::SHR) { 934 if (stub->operation() == Token::SHR) {
908 // TODO(olivf) Replace this by a SmiTagU Instruction. 935 // TODO(olivf) Replace this by a SmiTagU Instruction.
909 // 0x40000000: this number would convert to negative when interpreting 936 // 0x40000000: this number would convert to negative when interpreting
910 // the register as signed value; 937 // the register as signed value;
911 IfBuilder if_of(this); 938 IfBuilder if_of(this);
912 if_of.IfNot<HCompareNumericAndBranch>(result, 939 if_of.IfNot<HCompareNumericAndBranch>(result,
913 Add<HConstant>(static_cast<int>(SmiValuesAre32Bits() 940 Add<HConstant>(static_cast<int>(SmiValuesAre32Bits()
914 ? 0x80000000 : 0x40000000)), Token::EQ_STRICT); 941 ? 0x80000000 : 0x40000000)), Token::EQ_STRICT);
915 if_of.Then(); 942 if_of.Then();
916 if_of.ElseDeopt("UInt->Smi oveflow"); 943 if_of.ElseDeopt("UInt->Smi oveflow");
917 if_of.End(); 944 if_of.End();
918 } 945 }
919 } 946 }
920 result = EnforceNumberType(result, result_type); 947 result = EnforceNumberType(result, result_type);
921 } 948 }
922 949
923 // Reuse the double box if we are allowed to (i.e. chained binops). 950 // Reuse the double box of one of the operands if we are allowed to (i.e.
951 // chained binops).
924 if (stub->CanReuseDoubleBox()) { 952 if (stub->CanReuseDoubleBox()) {
925 HValue* reuse = (stub->mode() == OVERWRITE_LEFT) ? left : right; 953 HValue* operand = (stub->mode() == OVERWRITE_LEFT) ? left : right;
926 IfBuilder if_heap_number(this); 954 IfBuilder if_heap_number(this);
927 if_heap_number.IfNot<HIsSmiAndBranch>(reuse); 955 if_heap_number.IfNot<HIsSmiAndBranch>(operand);
928 if_heap_number.Then(); 956 if_heap_number.Then();
929 HValue* res_val = Add<HForceRepresentation>(result, 957 Add<HStoreNamedField>(operand, HObjectAccess::ForHeapNumberValue(), result);
930 Representation::Double()); 958 Push(operand);
931 HObjectAccess access = HObjectAccess::ForHeapNumberValue();
932 Add<HStoreNamedField>(reuse, access, res_val);
933 Push(reuse);
934 if_heap_number.Else(); 959 if_heap_number.Else();
935 Push(result); 960 Push(result);
936 if_heap_number.End(); 961 if_heap_number.End();
937 result = Pop(); 962 result = Pop();
938 } 963 }
939 964
940 return result; 965 return result;
941 } 966 }
942 967
943 968
(...skipping 195 matching lines...) Expand 10 before | Expand all | Expand 10 after
1139 restore_check.If<HCompareNumericAndBranch>(key, second_entry_index, 1164 restore_check.If<HCompareNumericAndBranch>(key, second_entry_index,
1140 Token::EQ); 1165 Token::EQ);
1141 restore_check.Then(); 1166 restore_check.Then();
1142 { 1167 {
1143 // Store the unoptimized code 1168 // Store the unoptimized code
1144 BuildInstallCode(js_function, shared_info); 1169 BuildInstallCode(js_function, shared_info);
1145 loop_builder.Break(); 1170 loop_builder.Break();
1146 } 1171 }
1147 restore_check.Else(); 1172 restore_check.Else();
1148 { 1173 {
1149 HValue* keyed_minus = AddInstruction(HSub::New(zone(), context(), key, 1174 HValue* keyed_minus = AddUncasted<HSub>(
1150 shared_function_entry_length)); 1175 key, shared_function_entry_length);
1151 HInstruction* keyed_lookup = Add<HLoadKeyed>(optimized_map, 1176 HInstruction* keyed_lookup = Add<HLoadKeyed>(optimized_map,
1152 keyed_minus, static_cast<HValue*>(NULL), FAST_ELEMENTS); 1177 keyed_minus, static_cast<HValue*>(NULL), FAST_ELEMENTS);
1153 IfBuilder done_check(this); 1178 IfBuilder done_check(this);
1154 done_check.If<HCompareObjectEqAndBranch>(native_context, 1179 done_check.If<HCompareObjectEqAndBranch>(native_context,
1155 keyed_lookup); 1180 keyed_lookup);
1156 done_check.Then(); 1181 done_check.Then();
1157 { 1182 {
1158 // Hit: fetch the optimized code. 1183 // Hit: fetch the optimized code.
1159 HValue* keyed_plus = AddInstruction(HAdd::New(zone(), context(), 1184 HValue* keyed_plus = AddUncasted<HAdd>(
1160 keyed_minus, graph()->GetConstant1())); 1185 keyed_minus, graph()->GetConstant1());
1161 HValue* code_object = Add<HLoadKeyed>(optimized_map, 1186 HValue* code_object = Add<HLoadKeyed>(optimized_map,
1162 keyed_plus, static_cast<HValue*>(NULL), FAST_ELEMENTS); 1187 keyed_plus, static_cast<HValue*>(NULL), FAST_ELEMENTS);
1163 BuildInstallOptimizedCode(js_function, native_context, code_object); 1188 BuildInstallOptimizedCode(js_function, native_context, code_object);
1164 1189
1165 // Fall out of the loop 1190 // Fall out of the loop
1166 loop_builder.Break(); 1191 loop_builder.Break();
1167 } 1192 }
1168 done_check.Else(); 1193 done_check.Else();
1169 done_check.End(); 1194 done_check.End();
1170 } 1195 }
(...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after
1232 return js_function; 1257 return js_function;
1233 } 1258 }
1234 1259
1235 1260
1236 Handle<Code> FastNewClosureStub::GenerateCode(Isolate* isolate) { 1261 Handle<Code> FastNewClosureStub::GenerateCode(Isolate* isolate) {
1237 return DoGenerateCode(isolate, this); 1262 return DoGenerateCode(isolate, this);
1238 } 1263 }
1239 1264
1240 1265
1241 } } // namespace v8::internal 1266 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « src/code-stubs.cc ('k') | src/codegen.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698