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

Side by Side Diff: src/x64/lithium-codegen-x64.cc

Issue 10539110: Add negative lookups to polymorphic loads in Crankshaft. (Closed) Base URL: http://v8.googlecode.com/svn/branches/bleeding_edge/
Patch Set: Created 8 years, 6 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/x64/lithium-codegen-x64.h ('k') | test/mjsunit/elements-transition-hoisting.js » ('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 2177 matching lines...) Expand 10 before | Expand all | Expand 10 after
2188 } else { 2188 } else {
2189 __ movq(result, FieldOperand(object, JSObject::kPropertiesOffset)); 2189 __ movq(result, FieldOperand(object, JSObject::kPropertiesOffset));
2190 __ movq(result, FieldOperand(result, instr->hydrogen()->offset())); 2190 __ movq(result, FieldOperand(result, instr->hydrogen()->offset()));
2191 } 2191 }
2192 } 2192 }
2193 2193
2194 2194
2195 void LCodeGen::EmitLoadFieldOrConstantFunction(Register result, 2195 void LCodeGen::EmitLoadFieldOrConstantFunction(Register result,
2196 Register object, 2196 Register object,
2197 Handle<Map> type, 2197 Handle<Map> type,
2198 Handle<String> name) { 2198 Handle<String> name,
2199 LEnvironment* env) {
2199 LookupResult lookup(isolate()); 2200 LookupResult lookup(isolate());
2200 type->LookupInDescriptors(NULL, *name, &lookup); 2201 type->LookupInDescriptors(NULL, *name, &lookup);
2201 ASSERT(lookup.IsFound() && 2202 ASSERT(lookup.IsFound() || lookup.IsCacheable());
2202 (lookup.type() == FIELD || lookup.type() == CONSTANT_FUNCTION)); 2203 if (lookup.IsFound() && lookup.type() == FIELD) {
2203 if (lookup.type() == FIELD) {
2204 int index = lookup.GetLocalFieldIndexFromMap(*type); 2204 int index = lookup.GetLocalFieldIndexFromMap(*type);
2205 int offset = index * kPointerSize; 2205 int offset = index * kPointerSize;
2206 if (index < 0) { 2206 if (index < 0) {
2207 // Negative property indices are in-object properties, indexed 2207 // Negative property indices are in-object properties, indexed
2208 // from the end of the fixed part of the object. 2208 // from the end of the fixed part of the object.
2209 __ movq(result, FieldOperand(object, offset + type->instance_size())); 2209 __ movq(result, FieldOperand(object, offset + type->instance_size()));
2210 } else { 2210 } else {
2211 // Non-negative property indices are in the properties array. 2211 // Non-negative property indices are in the properties array.
2212 __ movq(result, FieldOperand(object, JSObject::kPropertiesOffset)); 2212 __ movq(result, FieldOperand(object, JSObject::kPropertiesOffset));
2213 __ movq(result, FieldOperand(result, offset + FixedArray::kHeaderSize)); 2213 __ movq(result, FieldOperand(result, offset + FixedArray::kHeaderSize));
2214 } 2214 }
2215 } else { 2215 } else if (lookup.IsFound() && lookup.type() == CONSTANT_FUNCTION) {
2216 Handle<JSFunction> function(lookup.GetConstantFunctionFromMap(*type)); 2216 Handle<JSFunction> function(lookup.GetConstantFunctionFromMap(*type));
2217 __ LoadHeapObject(result, function); 2217 __ LoadHeapObject(result, function);
2218 } else {
2219 // Negative lookup.
2220 // Check prototypes.
2221 HeapObject* current = HeapObject::cast((*type)->prototype());
2222 Heap* heap = type->GetHeap();
2223 while (current != heap->null_value()) {
2224 Handle<HeapObject> link(current);
2225 __ LoadHeapObject(result, link);
2226 __ Cmp(FieldOperand(result, HeapObject::kMapOffset),
2227 Handle<Map>(JSObject::cast(current)->map()));
2228 DeoptimizeIf(not_equal, env);
2229 current = HeapObject::cast(current->map()->prototype());
2230 }
2231 __ LoadRoot(result, Heap::kUndefinedValueRootIndex);
2218 } 2232 }
2219 } 2233 }
2220 2234
2221 2235
2222 void LCodeGen::DoLoadNamedFieldPolymorphic(LLoadNamedFieldPolymorphic* instr) { 2236 void LCodeGen::DoLoadNamedFieldPolymorphic(LLoadNamedFieldPolymorphic* instr) {
2223 Register object = ToRegister(instr->object()); 2237 Register object = ToRegister(instr->object());
2224 Register result = ToRegister(instr->result()); 2238 Register result = ToRegister(instr->result());
2225 2239
2226 int map_count = instr->hydrogen()->types()->length(); 2240 int map_count = instr->hydrogen()->types()->length();
2227 bool need_generic = instr->hydrogen()->need_generic(); 2241 bool need_generic = instr->hydrogen()->need_generic();
2228 2242
2229 if (map_count == 0 && !need_generic) { 2243 if (map_count == 0 && !need_generic) {
2230 DeoptimizeIf(no_condition, instr->environment()); 2244 DeoptimizeIf(no_condition, instr->environment());
2231 return; 2245 return;
2232 } 2246 }
2233 Handle<String> name = instr->hydrogen()->name(); 2247 Handle<String> name = instr->hydrogen()->name();
2234 Label done; 2248 Label done;
2249 bool compact_code = true;
2250 for (int i = 0; i < map_count; ++i) {
2251 LookupResult lookup(isolate());
2252 Handle<Map> map = instr->hydrogen()->types()->at(i);
2253 map->LookupInDescriptors(NULL, *name, &lookup);
2254 if (!lookup.IsFound() ||
2255 (lookup.type() != FIELD && lookup.type() != CONSTANT_FUNCTION)) {
2256 // The two cases above cause a bounded amount of code to be emitted. This
2257 // is not necessarily the case for other lookup results.
2258 compact_code = false;
2259 break;
2260 }
2261 }
2235 for (int i = 0; i < map_count; ++i) { 2262 for (int i = 0; i < map_count; ++i) {
2236 bool last = (i == map_count - 1); 2263 bool last = (i == map_count - 1);
2237 Handle<Map> map = instr->hydrogen()->types()->at(i); 2264 Handle<Map> map = instr->hydrogen()->types()->at(i);
2238 __ Cmp(FieldOperand(object, HeapObject::kMapOffset), map); 2265 Label check_passed;
2266 __ CompareMap(object, map, &check_passed, ALLOW_ELEMENT_TRANSITION_MAPS);
2239 if (last && !need_generic) { 2267 if (last && !need_generic) {
2240 DeoptimizeIf(not_equal, instr->environment()); 2268 DeoptimizeIf(not_equal, instr->environment());
2241 EmitLoadFieldOrConstantFunction(result, object, map, name); 2269 __ bind(&check_passed);
2270 EmitLoadFieldOrConstantFunction(
2271 result, object, map, name, instr->environment());
2242 } else { 2272 } else {
2243 Label next; 2273 Label next;
2244 __ j(not_equal, &next, Label::kNear); 2274 __ j(not_equal, &next, Label::kNear);
2245 EmitLoadFieldOrConstantFunction(result, object, map, name); 2275 __ bind(&check_passed);
2246 __ jmp(&done, Label::kNear); 2276 EmitLoadFieldOrConstantFunction(
2277 result, object, map, name, instr->environment());
2278 __ jmp(&done, compact_code ? Label::kNear: Label::kFar);
2247 __ bind(&next); 2279 __ bind(&next);
2248 } 2280 }
2249 } 2281 }
2250 if (need_generic) { 2282 if (need_generic) {
2251 __ Move(rcx, name); 2283 __ Move(rcx, name);
2252 Handle<Code> ic = isolate()->builtins()->LoadIC_Initialize(); 2284 Handle<Code> ic = isolate()->builtins()->LoadIC_Initialize();
2253 CallCode(ic, RelocInfo::CODE_TARGET, instr); 2285 CallCode(ic, RelocInfo::CODE_TARGET, instr);
2254 } 2286 }
2255 __ bind(&done); 2287 __ bind(&done);
2256 } 2288 }
(...skipping 2648 matching lines...) Expand 10 before | Expand all | Expand 10 after
4905 FixedArray::kHeaderSize - kPointerSize)); 4937 FixedArray::kHeaderSize - kPointerSize));
4906 __ bind(&done); 4938 __ bind(&done);
4907 } 4939 }
4908 4940
4909 4941
4910 #undef __ 4942 #undef __
4911 4943
4912 } } // namespace v8::internal 4944 } } // namespace v8::internal
4913 4945
4914 #endif // V8_TARGET_ARCH_X64 4946 #endif // V8_TARGET_ARCH_X64
OLDNEW
« no previous file with comments | « src/x64/lithium-codegen-x64.h ('k') | test/mjsunit/elements-transition-hoisting.js » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698