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

Side by Side Diff: src/hydrogen.cc

Issue 6685052: Version 3.2.2. Fixed a number of crash and correctness bugs. Improved Cranksh... (Closed) Base URL: http://v8.googlecode.com/svn/trunk/
Patch Set: Created 9 years, 9 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/hydrogen.h ('k') | src/hydrogen-instructions.h » ('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 2011 the V8 project authors. All rights reserved. 1 // Copyright 2011 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 2118 matching lines...) Expand 10 before | Expand all | Expand 10 after
2129 2129
2130 void HGraphBuilder::VisitExpressions(ZoneList<Expression*>* exprs) { 2130 void HGraphBuilder::VisitExpressions(ZoneList<Expression*>* exprs) {
2131 for (int i = 0; i < exprs->length(); ++i) { 2131 for (int i = 0; i < exprs->length(); ++i) {
2132 VISIT_FOR_VALUE(exprs->at(i)); 2132 VISIT_FOR_VALUE(exprs->at(i));
2133 } 2133 }
2134 } 2134 }
2135 2135
2136 2136
2137 HGraph* HGraphBuilder::CreateGraph() { 2137 HGraph* HGraphBuilder::CreateGraph() {
2138 graph_ = new HGraph(info()); 2138 graph_ = new HGraph(info());
2139 if (FLAG_hydrogen_stats) HStatistics::Instance()->Initialize(info());
2140
2139 { 2141 {
2140 HPhase phase("Block building"); 2142 HPhase phase("Block building");
2141 current_block_ = graph()->entry_block(); 2143 current_block_ = graph()->entry_block();
2142 2144
2143 Scope* scope = info()->scope(); 2145 Scope* scope = info()->scope();
2144 if (scope->HasIllegalRedeclaration()) { 2146 if (scope->HasIllegalRedeclaration()) {
2145 Bailout("function with illegal redeclaration"); 2147 Bailout("function with illegal redeclaration");
2146 return NULL; 2148 return NULL;
2147 } 2149 }
2148 SetupScope(scope); 2150 SetupScope(scope);
(...skipping 1545 matching lines...) Expand 10 before | Expand all | Expand 10 after
3694 AddInstruction(new HCheckInstanceType(array, JS_ARRAY_TYPE, JS_ARRAY_TYPE)); 3696 AddInstruction(new HCheckInstanceType(array, JS_ARRAY_TYPE, JS_ARRAY_TYPE));
3695 instr = new HJSArrayLength(array); 3697 instr = new HJSArrayLength(array);
3696 3698
3697 } else if (expr->IsStringLength()) { 3699 } else if (expr->IsStringLength()) {
3698 HValue* string = Pop(); 3700 HValue* string = Pop();
3699 AddInstruction(new HCheckNonSmi(string)); 3701 AddInstruction(new HCheckNonSmi(string));
3700 AddInstruction(new HCheckInstanceType(string, 3702 AddInstruction(new HCheckInstanceType(string,
3701 FIRST_STRING_TYPE, 3703 FIRST_STRING_TYPE,
3702 LAST_STRING_TYPE)); 3704 LAST_STRING_TYPE));
3703 instr = new HStringLength(string); 3705 instr = new HStringLength(string);
3706 } else if (expr->IsStringAccess()) {
3707 VISIT_FOR_VALUE(expr->key());
3708 HValue* index = Pop();
3709 HValue* string = Pop();
3710 HStringCharCodeAt* char_code = BuildStringCharCodeAt(string, index);
3711 AddInstruction(char_code);
3712 instr = new HStringCharFromCode(char_code);
3704 3713
3705 } else if (expr->IsFunctionPrototype()) { 3714 } else if (expr->IsFunctionPrototype()) {
3706 HValue* function = Pop(); 3715 HValue* function = Pop();
3707 AddInstruction(new HCheckNonSmi(function)); 3716 AddInstruction(new HCheckNonSmi(function));
3708 instr = new HLoadFunctionPrototype(function); 3717 instr = new HLoadFunctionPrototype(function);
3709 3718
3710 } else if (expr->key()->IsPropertyName()) { 3719 } else if (expr->key()->IsPropertyName()) {
3711 Handle<String> name = expr->key()->AsLiteral()->AsPropertyName(); 3720 Handle<String> name = expr->key()->AsLiteral()->AsPropertyName();
3712 ZoneMapList* types = expr->GetReceiverTypes(); 3721 ZoneMapList* types = expr->GetReceiverTypes();
3713 3722
(...skipping 360 matching lines...) Expand 10 before | Expand all | Expand 10 after
4074 HValue* receiver, 4083 HValue* receiver,
4075 Handle<Map> receiver_map, 4084 Handle<Map> receiver_map,
4076 CheckType check_type) { 4085 CheckType check_type) {
4077 ASSERT(check_type != RECEIVER_MAP_CHECK || !receiver_map.is_null()); 4086 ASSERT(check_type != RECEIVER_MAP_CHECK || !receiver_map.is_null());
4078 // Try to inline calls like Math.* as operations in the calling function. 4087 // Try to inline calls like Math.* as operations in the calling function.
4079 if (!expr->target()->shared()->HasBuiltinFunctionId()) return false; 4088 if (!expr->target()->shared()->HasBuiltinFunctionId()) return false;
4080 BuiltinFunctionId id = expr->target()->shared()->builtin_function_id(); 4089 BuiltinFunctionId id = expr->target()->shared()->builtin_function_id();
4081 int argument_count = expr->arguments()->length() + 1; // Plus receiver. 4090 int argument_count = expr->arguments()->length() + 1; // Plus receiver.
4082 switch (id) { 4091 switch (id) {
4083 case kStringCharCodeAt: 4092 case kStringCharCodeAt:
4093 case kStringCharAt:
4084 if (argument_count == 2 && check_type == STRING_CHECK) { 4094 if (argument_count == 2 && check_type == STRING_CHECK) {
4085 HValue* index = Pop(); 4095 HValue* index = Pop();
4086 HValue* string = Pop(); 4096 HValue* string = Pop();
4087 ASSERT(!expr->holder().is_null()); 4097 ASSERT(!expr->holder().is_null());
4088 AddInstruction(new HCheckPrototypeMaps( 4098 AddInstruction(new HCheckPrototypeMaps(
4089 oracle()->GetPrototypeForPrimitiveCheck(STRING_CHECK), 4099 oracle()->GetPrototypeForPrimitiveCheck(STRING_CHECK),
4090 expr->holder())); 4100 expr->holder()));
4091 HStringCharCodeAt* result = BuildStringCharCodeAt(string, index); 4101 HStringCharCodeAt* char_code = BuildStringCharCodeAt(string, index);
4102 if (id == kStringCharCodeAt) {
4103 ast_context()->ReturnInstruction(char_code, expr->id());
4104 return true;
4105 }
4106 AddInstruction(char_code);
4107 HStringCharFromCode* result = new HStringCharFromCode(char_code);
4092 ast_context()->ReturnInstruction(result, expr->id()); 4108 ast_context()->ReturnInstruction(result, expr->id());
4093 return true; 4109 return true;
4094 } 4110 }
4095 break; 4111 break;
4096 case kMathRound: 4112 case kMathRound:
4097 case kMathFloor: 4113 case kMathFloor:
4098 case kMathAbs: 4114 case kMathAbs:
4099 case kMathSqrt: 4115 case kMathSqrt:
4100 case kMathLog: 4116 case kMathLog:
4101 case kMathSin: 4117 case kMathSin:
(...skipping 156 matching lines...) Expand 10 before | Expand all | Expand 10 after
4258 Handle<Map> receiver_map = 4274 Handle<Map> receiver_map =
4259 (types == NULL) ? Handle<Map>::null() : types->first(); 4275 (types == NULL) ? Handle<Map>::null() : types->first();
4260 if (TryInlineBuiltinFunction(expr, 4276 if (TryInlineBuiltinFunction(expr,
4261 receiver, 4277 receiver,
4262 receiver_map, 4278 receiver_map,
4263 expr->check_type())) { 4279 expr->check_type())) {
4264 return; 4280 return;
4265 } 4281 }
4266 4282
4267 if (HasCustomCallGenerator(expr->target()) || 4283 if (HasCustomCallGenerator(expr->target()) ||
4284 CallOptimization(*expr->target()).is_simple_api_call() ||
4268 expr->check_type() != RECEIVER_MAP_CHECK) { 4285 expr->check_type() != RECEIVER_MAP_CHECK) {
4269 // When the target has a custom call IC generator, use the IC, 4286 // When the target has a custom call IC generator, use the IC,
4270 // because it is likely to generate better code. Also use the 4287 // because it is likely to generate better code. Similarly, we
4271 // IC when a primitive receiver check is required. 4288 // generate better call stubs for some API functions.
4289 // Also use the IC when a primitive receiver check is required.
4272 HContext* context = new HContext; 4290 HContext* context = new HContext;
4273 AddInstruction(context); 4291 AddInstruction(context);
4274 call = PreProcessCall(new HCallNamed(context, name, argument_count)); 4292 call = PreProcessCall(new HCallNamed(context, name, argument_count));
4275 } else { 4293 } else {
4276 AddCheckConstantFunction(expr, receiver, receiver_map, true); 4294 AddCheckConstantFunction(expr, receiver, receiver_map, true);
4277 4295
4278 if (TryInline(expr)) { 4296 if (TryInline(expr)) {
4279 return; 4297 return;
4280 } else { 4298 } else {
4281 // Check for bailout, as the TryInline call in the if condition above 4299 // Check for bailout, as the TryInline call in the if condition above
(...skipping 885 matching lines...) Expand 10 before | Expand all | Expand 10 after
5167 VISIT_FOR_VALUE(call->arguments()->at(1)); 5185 VISIT_FOR_VALUE(call->arguments()->at(1));
5168 HValue* index = Pop(); 5186 HValue* index = Pop();
5169 HValue* string = Pop(); 5187 HValue* string = Pop();
5170 HStringCharCodeAt* result = BuildStringCharCodeAt(string, index); 5188 HStringCharCodeAt* result = BuildStringCharCodeAt(string, index);
5171 ast_context()->ReturnInstruction(result, call->id()); 5189 ast_context()->ReturnInstruction(result, call->id());
5172 } 5190 }
5173 5191
5174 5192
5175 // Fast support for string.charAt(n) and string[n]. 5193 // Fast support for string.charAt(n) and string[n].
5176 void HGraphBuilder::GenerateStringCharFromCode(CallRuntime* call) { 5194 void HGraphBuilder::GenerateStringCharFromCode(CallRuntime* call) {
5177 BAILOUT("inlined runtime function: StringCharFromCode"); 5195 ASSERT(call->arguments()->length() == 1);
5196 VISIT_FOR_VALUE(call->arguments()->at(0));
5197 HValue* char_code = Pop();
5198 HStringCharFromCode* result = new HStringCharFromCode(char_code);
5199 ast_context()->ReturnInstruction(result, call->id());
5178 } 5200 }
5179 5201
5180 5202
5181 // Fast support for string.charAt(n) and string[n]. 5203 // Fast support for string.charAt(n) and string[n].
5182 void HGraphBuilder::GenerateStringCharAt(CallRuntime* call) { 5204 void HGraphBuilder::GenerateStringCharAt(CallRuntime* call) {
5183 ASSERT_EQ(2, call->arguments()->length()); 5205 ASSERT(call->arguments()->length() == 2);
5184 VisitArgumentList(call->arguments()); 5206 VISIT_FOR_VALUE(call->arguments()->at(0));
5185 CHECK_BAILOUT; 5207 VISIT_FOR_VALUE(call->arguments()->at(1));
5186 HContext* context = new HContext; 5208 HValue* index = Pop();
5187 AddInstruction(context); 5209 HValue* string = Pop();
5188 HCallStub* result = new HCallStub(context, CodeStub::StringCharAt, 2); 5210 HStringCharCodeAt* char_code = BuildStringCharCodeAt(string, index);
5189 Drop(2); 5211 AddInstruction(char_code);
5212 HStringCharFromCode* result = new HStringCharFromCode(char_code);
5190 ast_context()->ReturnInstruction(result, call->id()); 5213 ast_context()->ReturnInstruction(result, call->id());
5191 } 5214 }
5192 5215
5193 5216
5194 // Fast support for object equality testing. 5217 // Fast support for object equality testing.
5195 void HGraphBuilder::GenerateObjectEquals(CallRuntime* call) { 5218 void HGraphBuilder::GenerateObjectEquals(CallRuntime* call) {
5196 ASSERT(call->arguments()->length() == 2); 5219 ASSERT(call->arguments()->length() == 2);
5197 VISIT_FOR_VALUE(call->arguments()->at(0)); 5220 VISIT_FOR_VALUE(call->arguments()->at(0));
5198 VISIT_FOR_VALUE(call->arguments()->at(1)); 5221 VISIT_FOR_VALUE(call->arguments()->at(1));
5199 HValue* right = Pop(); 5222 HValue* right = Pop();
(...skipping 529 matching lines...) Expand 10 before | Expand all | Expand 10 after
5729 } 5752 }
5730 } 5753 }
5731 } 5754 }
5732 } 5755 }
5733 5756
5734 5757
5735 void HTracer::TraceLiveRanges(const char* name, LAllocator* allocator) { 5758 void HTracer::TraceLiveRanges(const char* name, LAllocator* allocator) {
5736 Tag tag(this, "intervals"); 5759 Tag tag(this, "intervals");
5737 PrintStringProperty("name", name); 5760 PrintStringProperty("name", name);
5738 5761
5739 const ZoneList<LiveRange*>* fixed_d = allocator->fixed_double_live_ranges(); 5762 const Vector<LiveRange*>* fixed_d = allocator->fixed_double_live_ranges();
5740 for (int i = 0; i < fixed_d->length(); ++i) { 5763 for (int i = 0; i < fixed_d->length(); ++i) {
5741 TraceLiveRange(fixed_d->at(i), "fixed"); 5764 TraceLiveRange(fixed_d->at(i), "fixed");
5742 } 5765 }
5743 5766
5744 const ZoneList<LiveRange*>* fixed = allocator->fixed_live_ranges(); 5767 const Vector<LiveRange*>* fixed = allocator->fixed_live_ranges();
5745 for (int i = 0; i < fixed->length(); ++i) { 5768 for (int i = 0; i < fixed->length(); ++i) {
5746 TraceLiveRange(fixed->at(i), "fixed"); 5769 TraceLiveRange(fixed->at(i), "fixed");
5747 } 5770 }
5748 5771
5749 const ZoneList<LiveRange*>* live_ranges = allocator->live_ranges(); 5772 const ZoneList<LiveRange*>* live_ranges = allocator->live_ranges();
5750 for (int i = 0; i < live_ranges->length(); ++i) { 5773 for (int i = 0; i < live_ranges->length(); ++i) {
5751 TraceLiveRange(live_ranges->at(i), "object"); 5774 TraceLiveRange(live_ranges->at(i), "object");
5752 } 5775 }
5753 } 5776 }
5754 5777
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after
5805 } 5828 }
5806 } 5829 }
5807 5830
5808 5831
5809 void HTracer::FlushToFile() { 5832 void HTracer::FlushToFile() {
5810 AppendChars(filename_, *trace_.ToCString(), trace_.length(), false); 5833 AppendChars(filename_, *trace_.ToCString(), trace_.length(), false);
5811 trace_.Reset(); 5834 trace_.Reset();
5812 } 5835 }
5813 5836
5814 5837
5838 void HStatistics::Initialize(CompilationInfo* info) {
5839 source_size_ += info->shared_info()->SourceSize();
5840 }
5841
5842
5815 void HStatistics::Print() { 5843 void HStatistics::Print() {
5816 PrintF("Timing results:\n"); 5844 PrintF("Timing results:\n");
5817 int64_t sum = 0; 5845 int64_t sum = 0;
5818 for (int i = 0; i < timing_.length(); ++i) { 5846 for (int i = 0; i < timing_.length(); ++i) {
5819 sum += timing_[i]; 5847 sum += timing_[i];
5820 } 5848 }
5821 5849
5822 for (int i = 0; i < names_.length(); ++i) { 5850 for (int i = 0; i < names_.length(); ++i) {
5823 PrintF("%30s", names_[i]); 5851 PrintF("%30s", names_[i]);
5824 double ms = static_cast<double>(timing_[i]) / 1000; 5852 double ms = static_cast<double>(timing_[i]) / 1000;
5825 double percent = static_cast<double>(timing_[i]) * 100 / sum; 5853 double percent = static_cast<double>(timing_[i]) * 100 / sum;
5826 PrintF(" - %7.3f ms / %4.1f %% ", ms, percent); 5854 PrintF(" - %7.3f ms / %4.1f %% ", ms, percent);
5827 5855
5828 unsigned size = sizes_[i]; 5856 unsigned size = sizes_[i];
5829 double size_percent = static_cast<double>(size) * 100 / total_size_; 5857 double size_percent = static_cast<double>(size) * 100 / total_size_;
5830 PrintF(" %8u bytes / %4.1f %%\n", size, size_percent); 5858 PrintF(" %8u bytes / %4.1f %%\n", size, size_percent);
5831 } 5859 }
5832 PrintF("%30s - %7.3f ms %8u bytes\n", "Sum", 5860 double source_size_in_kb = static_cast<double>(source_size_) / 1024;
5833 static_cast<double>(sum) / 1000, 5861 PrintF("%30s - %7.3f ms %7.3f bytes\n", "Sum",
5834 total_size_); 5862 (static_cast<double>(sum) / 1000) / source_size_in_kb,
5863 total_size_ / source_size_in_kb);
5835 PrintF("---------------------------------------------------------------\n"); 5864 PrintF("---------------------------------------------------------------\n");
5836 PrintF("%30s - %7.3f ms (%.1f times slower than full code gen)\n", 5865 PrintF("%30s - %7.3f ms (%.1f times slower than full code gen)\n",
5837 "Total", 5866 "Total",
5838 static_cast<double>(total_) / 1000, 5867 static_cast<double>(total_) / 1000,
5839 static_cast<double>(total_) / full_code_gen_); 5868 static_cast<double>(total_) / full_code_gen_);
5840 } 5869 }
5841 5870
5842 5871
5843 void HStatistics::SaveTiming(const char* name, int64_t ticks, unsigned size) { 5872 void HStatistics::SaveTiming(const char* name, int64_t ticks, unsigned size) {
5844 if (name == HPhase::kFullCodeGen) { 5873 if (name == HPhase::kFullCodeGen) {
(...skipping 24 matching lines...) Expand all
5869 HGraph* graph, 5898 HGraph* graph,
5870 LChunk* chunk, 5899 LChunk* chunk,
5871 LAllocator* allocator) { 5900 LAllocator* allocator) {
5872 name_ = name; 5901 name_ = name;
5873 graph_ = graph; 5902 graph_ = graph;
5874 chunk_ = chunk; 5903 chunk_ = chunk;
5875 allocator_ = allocator; 5904 allocator_ = allocator;
5876 if (allocator != NULL && chunk_ == NULL) { 5905 if (allocator != NULL && chunk_ == NULL) {
5877 chunk_ = allocator->chunk(); 5906 chunk_ = allocator->chunk();
5878 } 5907 }
5879 if (FLAG_time_hydrogen) start_ = OS::Ticks(); 5908 if (FLAG_hydrogen_stats) start_ = OS::Ticks();
5880 start_allocation_size_ = Zone::allocation_size_; 5909 start_allocation_size_ = Zone::allocation_size_;
5881 } 5910 }
5882 5911
5883 5912
5884 void HPhase::End() const { 5913 void HPhase::End() const {
5885 if (FLAG_time_hydrogen) { 5914 if (FLAG_hydrogen_stats) {
5886 int64_t end = OS::Ticks(); 5915 int64_t end = OS::Ticks();
5887 unsigned size = Zone::allocation_size_ - start_allocation_size_; 5916 unsigned size = Zone::allocation_size_ - start_allocation_size_;
5888 HStatistics::Instance()->SaveTiming(name_, end - start_, size); 5917 HStatistics::Instance()->SaveTiming(name_, end - start_, size);
5889 } 5918 }
5890 5919
5891 if (FLAG_trace_hydrogen) { 5920 if (FLAG_trace_hydrogen) {
5892 if (graph_ != NULL) HTracer::Instance()->TraceHydrogen(name_, graph_); 5921 if (graph_ != NULL) HTracer::Instance()->TraceHydrogen(name_, graph_);
5893 if (chunk_ != NULL) HTracer::Instance()->TraceLithium(name_, chunk_); 5922 if (chunk_ != NULL) HTracer::Instance()->TraceLithium(name_, chunk_);
5894 if (allocator_ != NULL) { 5923 if (allocator_ != NULL) {
5895 HTracer::Instance()->TraceLiveRanges(name_, allocator_); 5924 HTracer::Instance()->TraceLiveRanges(name_, allocator_);
5896 } 5925 }
5897 } 5926 }
5898 5927
5899 #ifdef DEBUG 5928 #ifdef DEBUG
5900 if (graph_ != NULL) graph_->Verify(); 5929 if (graph_ != NULL) graph_->Verify();
5901 if (allocator_ != NULL) allocator_->Verify(); 5930 if (allocator_ != NULL) allocator_->Verify();
5902 #endif 5931 #endif
5903 } 5932 }
5904 5933
5905 } } // namespace v8::internal 5934 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « src/hydrogen.h ('k') | src/hydrogen-instructions.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698