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

Side by Side Diff: src/hydrogen.cc

Issue 264973013: Don't add code dependencies eagerly for HCheckMaps. (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: REBASE Created 6 years, 7 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 2013 the V8 project authors. All rights reserved. 1 // Copyright 2013 the V8 project authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "hydrogen.h" 5 #include "hydrogen.h"
6 6
7 #include <algorithm> 7 #include <algorithm>
8 8
9 #include "v8.h" 9 #include "v8.h"
10 #include "allocation-site-scopes.h" 10 #include "allocation-site-scopes.h"
(...skipping 1219 matching lines...) Expand 10 before | Expand all | Expand 10 after
1230 return Add<HCheckHeapObject>(obj); 1230 return Add<HCheckHeapObject>(obj);
1231 } 1231 }
1232 1232
1233 1233
1234 void HGraphBuilder::FinishExitWithHardDeoptimization(const char* reason) { 1234 void HGraphBuilder::FinishExitWithHardDeoptimization(const char* reason) {
1235 Add<HDeoptimize>(reason, Deoptimizer::EAGER); 1235 Add<HDeoptimize>(reason, Deoptimizer::EAGER);
1236 FinishExitCurrentBlock(New<HAbnormalExit>()); 1236 FinishExitCurrentBlock(New<HAbnormalExit>());
1237 } 1237 }
1238 1238
1239 1239
1240 HValue* HGraphBuilder::BuildCheckMap(HValue* obj, Handle<Map> map) {
1241 return Add<HCheckMaps>(obj, map, top_info());
1242 }
1243
1244
1245 HValue* HGraphBuilder::BuildCheckString(HValue* string) { 1240 HValue* HGraphBuilder::BuildCheckString(HValue* string) {
1246 if (!string->type().IsString()) { 1241 if (!string->type().IsString()) {
1247 ASSERT(!string->IsConstant() || 1242 ASSERT(!string->IsConstant() ||
1248 !HConstant::cast(string)->HasStringValue()); 1243 !HConstant::cast(string)->HasStringValue());
1249 BuildCheckHeapObject(string); 1244 BuildCheckHeapObject(string);
1250 return Add<HCheckInstanceType>(string, HCheckInstanceType::IS_STRING); 1245 return Add<HCheckInstanceType>(string, HCheckInstanceType::IS_STRING);
1251 } 1246 }
1252 return string; 1247 return string;
1253 } 1248 }
1254 1249
(...skipping 880 matching lines...) Expand 10 before | Expand all | Expand 10 after
2135 (elements_kind == FAST_ELEMENTS && access_type == STORE)) { 2130 (elements_kind == FAST_ELEMENTS && access_type == STORE)) {
2136 checked_object->ClearDependsOnFlag(kElementsKind); 2131 checked_object->ClearDependsOnFlag(kElementsKind);
2137 } 2132 }
2138 2133
2139 bool fast_smi_only_elements = IsFastSmiElementsKind(elements_kind); 2134 bool fast_smi_only_elements = IsFastSmiElementsKind(elements_kind);
2140 bool fast_elements = IsFastObjectElementsKind(elements_kind); 2135 bool fast_elements = IsFastObjectElementsKind(elements_kind);
2141 HValue* elements = AddLoadElements(checked_object); 2136 HValue* elements = AddLoadElements(checked_object);
2142 if (access_type == STORE && (fast_elements || fast_smi_only_elements) && 2137 if (access_type == STORE && (fast_elements || fast_smi_only_elements) &&
2143 store_mode != STORE_NO_TRANSITION_HANDLE_COW) { 2138 store_mode != STORE_NO_TRANSITION_HANDLE_COW) {
2144 HCheckMaps* check_cow_map = Add<HCheckMaps>( 2139 HCheckMaps* check_cow_map = Add<HCheckMaps>(
2145 elements, isolate()->factory()->fixed_array_map(), top_info()); 2140 elements, isolate()->factory()->fixed_array_map());
2146 check_cow_map->ClearDependsOnFlag(kElementsKind); 2141 check_cow_map->ClearDependsOnFlag(kElementsKind);
2147 } 2142 }
2148 HInstruction* length = NULL; 2143 HInstruction* length = NULL;
2149 if (is_js_array) { 2144 if (is_js_array) {
2150 length = Add<HLoadNamedField>( 2145 length = Add<HLoadNamedField>(
2151 checked_object, static_cast<HValue*>(NULL), 2146 checked_object, static_cast<HValue*>(NULL),
2152 HObjectAccess::ForArrayLength(elements_kind)); 2147 HObjectAccess::ForArrayLength(elements_kind));
2153 } else { 2148 } else {
2154 length = AddLoadFixedArrayLength(elements); 2149 length = AddLoadFixedArrayLength(elements);
2155 } 2150 }
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after
2209 } else { 2204 } else {
2210 checked_key = Add<HBoundsCheck>(key, length); 2205 checked_key = Add<HBoundsCheck>(key, length);
2211 2206
2212 if (access_type == STORE && (fast_elements || fast_smi_only_elements)) { 2207 if (access_type == STORE && (fast_elements || fast_smi_only_elements)) {
2213 if (store_mode == STORE_NO_TRANSITION_HANDLE_COW) { 2208 if (store_mode == STORE_NO_TRANSITION_HANDLE_COW) {
2214 NoObservableSideEffectsScope no_effects(this); 2209 NoObservableSideEffectsScope no_effects(this);
2215 elements = BuildCopyElementsOnWrite(checked_object, elements, 2210 elements = BuildCopyElementsOnWrite(checked_object, elements,
2216 elements_kind, length); 2211 elements_kind, length);
2217 } else { 2212 } else {
2218 HCheckMaps* check_cow_map = Add<HCheckMaps>( 2213 HCheckMaps* check_cow_map = Add<HCheckMaps>(
2219 elements, isolate()->factory()->fixed_array_map(), top_info()); 2214 elements, isolate()->factory()->fixed_array_map());
2220 check_cow_map->ClearDependsOnFlag(kElementsKind); 2215 check_cow_map->ClearDependsOnFlag(kElementsKind);
2221 } 2216 }
2222 } 2217 }
2223 } 2218 }
2224 return AddElementAccess(elements, checked_key, val, checked_object, 2219 return AddElementAccess(elements, checked_key, val, checked_object,
2225 elements_kind, access_type, load_mode); 2220 elements_kind, access_type, load_mode);
2226 } 2221 }
2227 2222
2228 2223
2229 2224
(...skipping 447 matching lines...) Expand 10 before | Expand all | Expand 10 after
2677 2672
2678 if (some_case_missing) { 2673 if (some_case_missing) {
2679 if_nil.Then(); 2674 if_nil.Then();
2680 if_nil.Else(); 2675 if_nil.Else();
2681 if (type->NumClasses() == 1) { 2676 if (type->NumClasses() == 1) {
2682 BuildCheckHeapObject(value); 2677 BuildCheckHeapObject(value);
2683 // For ICs, the map checked below is a sentinel map that gets replaced by 2678 // For ICs, the map checked below is a sentinel map that gets replaced by
2684 // the monomorphic map when the code is used as a template to generate a 2679 // the monomorphic map when the code is used as a template to generate a
2685 // new IC. For optimized functions, there is no sentinel map, the map 2680 // new IC. For optimized functions, there is no sentinel map, the map
2686 // emitted below is the actual monomorphic map. 2681 // emitted below is the actual monomorphic map.
2687 BuildCheckMap(value, type->Classes().Current()); 2682 Add<HCheckMaps>(value, type->Classes().Current());
2688 } else { 2683 } else {
2689 if_nil.Deopt("Too many undetectable types"); 2684 if_nil.Deopt("Too many undetectable types");
2690 } 2685 }
2691 } 2686 }
2692 2687
2693 if_nil.CaptureContinuation(continuation); 2688 if_nil.CaptureContinuation(continuation);
2694 } 2689 }
2695 2690
2696 2691
2697 void HGraphBuilder::BuildCreateAllocationMemento( 2692 void HGraphBuilder::BuildCreateAllocationMemento(
(...skipping 2431 matching lines...) Expand 10 before | Expand all | Expand 10 after
5129 Handle<Map> map = property->GetReceiverType(); 5124 Handle<Map> map = property->GetReceiverType();
5130 Handle<String> name = property->key()->AsPropertyName(); 5125 Handle<String> name = property->key()->AsPropertyName();
5131 HInstruction* store; 5126 HInstruction* store;
5132 if (map.is_null()) { 5127 if (map.is_null()) {
5133 // If we don't know the monomorphic type, do a generic store. 5128 // If we don't know the monomorphic type, do a generic store.
5134 CHECK_ALIVE(store = BuildNamedGeneric( 5129 CHECK_ALIVE(store = BuildNamedGeneric(
5135 STORE, literal, name, value)); 5130 STORE, literal, name, value));
5136 } else { 5131 } else {
5137 PropertyAccessInfo info(this, STORE, ToType(map), name); 5132 PropertyAccessInfo info(this, STORE, ToType(map), name);
5138 if (info.CanAccessMonomorphic()) { 5133 if (info.CanAccessMonomorphic()) {
5139 HValue* checked_literal = BuildCheckMap(literal, map); 5134 HValue* checked_literal = Add<HCheckMaps>(literal, map);
5140 ASSERT(!info.lookup()->IsPropertyCallbacks()); 5135 ASSERT(!info.lookup()->IsPropertyCallbacks());
5141 store = BuildMonomorphicAccess( 5136 store = BuildMonomorphicAccess(
5142 &info, literal, checked_literal, value, 5137 &info, literal, checked_literal, value,
5143 BailoutId::None(), BailoutId::None()); 5138 BailoutId::None(), BailoutId::None());
5144 } else { 5139 } else {
5145 CHECK_ALIVE(store = BuildNamedGeneric( 5140 CHECK_ALIVE(store = BuildNamedGeneric(
5146 STORE, literal, name, value)); 5141 STORE, literal, name, value));
5147 } 5142 }
5148 } 5143 }
5149 AddInstruction(store); 5144 AddInstruction(store);
(...skipping 106 matching lines...) Expand 10 before | Expand all | Expand 10 after
5256 // TODO(mvstanton): Consider a flag to turn off creation of any 5251 // TODO(mvstanton): Consider a flag to turn off creation of any
5257 // AllocationMementos for this call: we are in crankshaft and should have 5252 // AllocationMementos for this call: we are in crankshaft and should have
5258 // learned enough about transition behavior to stop emitting mementos. 5253 // learned enough about transition behavior to stop emitting mementos.
5259 Runtime::FunctionId function_id = Runtime::kHiddenCreateArrayLiteral; 5254 Runtime::FunctionId function_id = Runtime::kHiddenCreateArrayLiteral;
5260 literal = Add<HCallRuntime>(isolate()->factory()->empty_string(), 5255 literal = Add<HCallRuntime>(isolate()->factory()->empty_string(),
5261 Runtime::FunctionForId(function_id), 5256 Runtime::FunctionForId(function_id),
5262 4); 5257 4);
5263 5258
5264 // De-opt if elements kind changed from boilerplate_elements_kind. 5259 // De-opt if elements kind changed from boilerplate_elements_kind.
5265 Handle<Map> map = Handle<Map>(boilerplate_object->map(), isolate()); 5260 Handle<Map> map = Handle<Map>(boilerplate_object->map(), isolate());
5266 literal = Add<HCheckMaps>(literal, map, top_info()); 5261 literal = Add<HCheckMaps>(literal, map);
5267 } 5262 }
5268 5263
5269 // The array is expected in the bailout environment during computation 5264 // The array is expected in the bailout environment during computation
5270 // of the property values and is the value of the entire expression. 5265 // of the property values and is the value of the entire expression.
5271 Push(literal); 5266 Push(literal);
5272 // The literal index is on the stack, too. 5267 // The literal index is on the stack, too.
5273 Push(Add<HConstant>(expr->literal_index())); 5268 Push(Add<HConstant>(expr->literal_index()));
5274 5269
5275 HInstruction* elements = NULL; 5270 HInstruction* elements = NULL;
5276 5271
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after
5309 } 5304 }
5310 5305
5311 Drop(1); // array literal index 5306 Drop(1); // array literal index
5312 return ast_context()->ReturnValue(Pop()); 5307 return ast_context()->ReturnValue(Pop());
5313 } 5308 }
5314 5309
5315 5310
5316 HCheckMaps* HOptimizedGraphBuilder::AddCheckMap(HValue* object, 5311 HCheckMaps* HOptimizedGraphBuilder::AddCheckMap(HValue* object,
5317 Handle<Map> map) { 5312 Handle<Map> map) {
5318 BuildCheckHeapObject(object); 5313 BuildCheckHeapObject(object);
5319 return Add<HCheckMaps>(object, map, top_info()); 5314 return Add<HCheckMaps>(object, map);
5320 } 5315 }
5321 5316
5322 5317
5323 HInstruction* HOptimizedGraphBuilder::BuildLoadNamedField( 5318 HInstruction* HOptimizedGraphBuilder::BuildLoadNamedField(
5324 PropertyAccessInfo* info, 5319 PropertyAccessInfo* info,
5325 HValue* checked_object) { 5320 HValue* checked_object) {
5326 // See if this is a load for an immutable property 5321 // See if this is a load for an immutable property
5327 if (checked_object->ActualValue()->IsConstant() && 5322 if (checked_object->ActualValue()->IsConstant() &&
5328 info->lookup()->IsCacheable() && 5323 info->lookup()->IsCacheable() &&
5329 info->lookup()->IsReadOnly() && info->lookup()->IsDontDelete()) { 5324 info->lookup()->IsReadOnly() && info->lookup()->IsDontDelete()) {
(...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after
5392 checked_object, static_cast<HValue*>(NULL), heap_number_access); 5387 checked_object, static_cast<HValue*>(NULL), heap_number_access);
5393 heap_number->set_type(HType::HeapNumber()); 5388 heap_number->set_type(HType::HeapNumber());
5394 instr = New<HStoreNamedField>(heap_number, 5389 instr = New<HStoreNamedField>(heap_number,
5395 HObjectAccess::ForHeapNumberValue(), 5390 HObjectAccess::ForHeapNumberValue(),
5396 value, STORE_TO_INITIALIZED_ENTRY); 5391 value, STORE_TO_INITIALIZED_ENTRY);
5397 } 5392 }
5398 } else { 5393 } else {
5399 if (!info->field_maps()->is_empty()) { 5394 if (!info->field_maps()->is_empty()) {
5400 ASSERT(field_access.representation().IsHeapObject()); 5395 ASSERT(field_access.representation().IsHeapObject());
5401 BuildCheckHeapObject(value); 5396 BuildCheckHeapObject(value);
5402 if (info->field_maps()->length() == 1) { 5397 value = Add<HCheckMaps>(value, info->field_maps());
5403 // TODO(bmeurer): Also apply stable maps optimization to the else case!
5404 value = BuildCheckMap(value, info->field_maps()->first());
5405 } else {
5406 value = Add<HCheckMaps>(value, info->field_maps());
5407 }
5408 5398
5409 // TODO(bmeurer): This is a dirty hack to avoid repeating the smi check 5399 // TODO(bmeurer): This is a dirty hack to avoid repeating the smi check
5410 // that was already performed by the HCheckHeapObject above in the 5400 // that was already performed by the HCheckHeapObject above in the
5411 // HStoreNamedField below. We should really do this right instead and 5401 // HStoreNamedField below. We should really do this right instead and
5412 // make Crankshaft aware of Representation::HeapObject(). 5402 // make Crankshaft aware of Representation::HeapObject().
5413 field_access = field_access.WithRepresentation(Representation::Tagged()); 5403 field_access = field_access.WithRepresentation(Representation::Tagged());
5414 } 5404 }
5415 5405
5416 // This is a normal store. 5406 // This is a normal store.
5417 instr = New<HStoreNamedField>( 5407 instr = New<HStoreNamedField>(
(...skipping 933 matching lines...) Expand 10 before | Expand all | Expand 10 after
6351 6341
6352 6342
6353 HInstruction* HOptimizedGraphBuilder::BuildMonomorphicElementAccess( 6343 HInstruction* HOptimizedGraphBuilder::BuildMonomorphicElementAccess(
6354 HValue* object, 6344 HValue* object,
6355 HValue* key, 6345 HValue* key,
6356 HValue* val, 6346 HValue* val,
6357 HValue* dependency, 6347 HValue* dependency,
6358 Handle<Map> map, 6348 Handle<Map> map,
6359 PropertyAccessType access_type, 6349 PropertyAccessType access_type,
6360 KeyedAccessStoreMode store_mode) { 6350 KeyedAccessStoreMode store_mode) {
6361 HCheckMaps* checked_object = Add<HCheckMaps>(object, map, top_info(), 6351 HCheckMaps* checked_object = Add<HCheckMaps>(object, map, dependency);
6362 dependency);
6363 if (dependency) { 6352 if (dependency) {
6364 checked_object->ClearDependsOnFlag(kElementsKind); 6353 checked_object->ClearDependsOnFlag(kElementsKind);
6365 } 6354 }
6366 6355
6367 if (access_type == STORE && map->prototype()->IsJSObject()) { 6356 if (access_type == STORE && map->prototype()->IsJSObject()) {
6368 // monomorphic stores need a prototype chain check because shape 6357 // monomorphic stores need a prototype chain check because shape
6369 // changes could allow callbacks on elements in the chain that 6358 // changes could allow callbacks on elements in the chain that
6370 // aren't compatible with monomorphic keyed stores. 6359 // aren't compatible with monomorphic keyed stores.
6371 Handle<JSObject> prototype(JSObject::cast(map->prototype())); 6360 Handle<JSObject> prototype(JSObject::cast(map->prototype()));
6372 Object* holder = map->prototype(); 6361 Object* holder = map->prototype();
(...skipping 458 matching lines...) Expand 10 before | Expand all | Expand 10 after
6831 CHECK_ALIVE(VisitForValue(expr->obj())); 6820 CHECK_ALIVE(VisitForValue(expr->obj()));
6832 if ((!expr->IsFunctionPrototype() && !expr->key()->IsPropertyName()) || 6821 if ((!expr->IsFunctionPrototype() && !expr->key()->IsPropertyName()) ||
6833 expr->IsStringAccess()) { 6822 expr->IsStringAccess()) {
6834 CHECK_ALIVE(VisitForValue(expr->key())); 6823 CHECK_ALIVE(VisitForValue(expr->key()));
6835 } 6824 }
6836 6825
6837 BuildLoad(expr, expr->id()); 6826 BuildLoad(expr, expr->id());
6838 } 6827 }
6839 6828
6840 6829
6841 HInstruction* HGraphBuilder::BuildConstantMapCheck(Handle<JSObject> constant, 6830 HInstruction* HGraphBuilder::BuildConstantMapCheck(Handle<JSObject> constant) {
6842 CompilationInfo* info) { 6831 HCheckMaps* check = Add<HCheckMaps>(
6843 HConstant* constant_value = New<HConstant>(constant); 6832 Add<HConstant>(constant), handle(constant->map()));
6844 Handle<Map> map(constant->map(), info->isolate());
6845
6846 if (constant->map()->CanOmitMapChecks()) {
6847 Map::AddDependentCompilationInfo(
6848 map, DependentCode::kPrototypeCheckGroup, info);
6849 return constant_value;
6850 }
6851
6852 AddInstruction(constant_value);
6853 HCheckMaps* check = Add<HCheckMaps>(constant_value, map, info);
6854 check->ClearDependsOnFlag(kElementsKind); 6833 check->ClearDependsOnFlag(kElementsKind);
6855 return check; 6834 return check;
6856 } 6835 }
6857 6836
6858 6837
6859 HInstruction* HGraphBuilder::BuildCheckPrototypeMaps(Handle<JSObject> prototype, 6838 HInstruction* HGraphBuilder::BuildCheckPrototypeMaps(Handle<JSObject> prototype,
6860 Handle<JSObject> holder) { 6839 Handle<JSObject> holder) {
6861 while (holder.is_null() || !prototype.is_identical_to(holder)) { 6840 while (holder.is_null() || !prototype.is_identical_to(holder)) {
6862 BuildConstantMapCheck(prototype, top_info()); 6841 BuildConstantMapCheck(prototype);
6863 Object* next_prototype = prototype->GetPrototype(); 6842 Object* next_prototype = prototype->GetPrototype();
6864 if (next_prototype->IsNull()) return NULL; 6843 if (next_prototype->IsNull()) return NULL;
6865 CHECK(next_prototype->IsJSObject()); 6844 CHECK(next_prototype->IsJSObject());
6866 prototype = handle(JSObject::cast(next_prototype)); 6845 prototype = handle(JSObject::cast(next_prototype));
6867 } 6846 }
6868 6847 return BuildConstantMapCheck(prototype);
6869 HInstruction* checked_object = BuildConstantMapCheck(prototype, top_info());
6870 if (!checked_object->IsLinked()) AddInstruction(checked_object);
6871 return checked_object;
6872 } 6848 }
6873 6849
6874 6850
6875 void HOptimizedGraphBuilder::AddCheckPrototypeMaps(Handle<JSObject> holder, 6851 void HOptimizedGraphBuilder::AddCheckPrototypeMaps(Handle<JSObject> holder,
6876 Handle<Map> receiver_map) { 6852 Handle<Map> receiver_map) {
6877 if (!holder.is_null()) { 6853 if (!holder.is_null()) {
6878 Handle<JSObject> prototype(JSObject::cast(receiver_map->prototype())); 6854 Handle<JSObject> prototype(JSObject::cast(receiver_map->prototype()));
6879 BuildCheckPrototypeMaps(prototype, holder); 6855 BuildCheckPrototypeMaps(prototype, holder);
6880 } 6856 }
6881 } 6857 }
(...skipping 4785 matching lines...) Expand 10 before | Expand all | Expand 10 after
11667 if (ShouldProduceTraceOutput()) { 11643 if (ShouldProduceTraceOutput()) {
11668 isolate()->GetHTracer()->TraceHydrogen(name(), graph_); 11644 isolate()->GetHTracer()->TraceHydrogen(name(), graph_);
11669 } 11645 }
11670 11646
11671 #ifdef DEBUG 11647 #ifdef DEBUG
11672 graph_->Verify(false); // No full verify. 11648 graph_->Verify(false); // No full verify.
11673 #endif 11649 #endif
11674 } 11650 }
11675 11651
11676 } } // namespace v8::internal 11652 } } // 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