OLD | NEW |
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 2284 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2295 } else { | 2295 } else { |
2296 __ mov(result, FieldOperand(object, JSObject::kPropertiesOffset)); | 2296 __ mov(result, FieldOperand(object, JSObject::kPropertiesOffset)); |
2297 __ mov(result, FieldOperand(result, instr->hydrogen()->offset())); | 2297 __ mov(result, FieldOperand(result, instr->hydrogen()->offset())); |
2298 } | 2298 } |
2299 } | 2299 } |
2300 | 2300 |
2301 | 2301 |
2302 void LCodeGen::EmitLoadFieldOrConstantFunction(Register result, | 2302 void LCodeGen::EmitLoadFieldOrConstantFunction(Register result, |
2303 Register object, | 2303 Register object, |
2304 Handle<Map> type, | 2304 Handle<Map> type, |
2305 Handle<String> name) { | 2305 Handle<String> name, |
| 2306 LEnvironment* env) { |
2306 LookupResult lookup(isolate()); | 2307 LookupResult lookup(isolate()); |
2307 type->LookupInDescriptors(NULL, *name, &lookup); | 2308 type->LookupInDescriptors(NULL, *name, &lookup); |
2308 ASSERT(lookup.IsFound() && | 2309 ASSERT(lookup.IsFound() || lookup.IsCacheable()); |
2309 (lookup.type() == FIELD || lookup.type() == CONSTANT_FUNCTION)); | 2310 if (lookup.IsFound() && lookup.type() == FIELD) { |
2310 if (lookup.type() == FIELD) { | |
2311 int index = lookup.GetLocalFieldIndexFromMap(*type); | 2311 int index = lookup.GetLocalFieldIndexFromMap(*type); |
2312 int offset = index * kPointerSize; | 2312 int offset = index * kPointerSize; |
2313 if (index < 0) { | 2313 if (index < 0) { |
2314 // Negative property indices are in-object properties, indexed | 2314 // Negative property indices are in-object properties, indexed |
2315 // from the end of the fixed part of the object. | 2315 // from the end of the fixed part of the object. |
2316 __ mov(result, FieldOperand(object, offset + type->instance_size())); | 2316 __ mov(result, FieldOperand(object, offset + type->instance_size())); |
2317 } else { | 2317 } else { |
2318 // Non-negative property indices are in the properties array. | 2318 // Non-negative property indices are in the properties array. |
2319 __ mov(result, FieldOperand(object, JSObject::kPropertiesOffset)); | 2319 __ mov(result, FieldOperand(object, JSObject::kPropertiesOffset)); |
2320 __ mov(result, FieldOperand(result, offset + FixedArray::kHeaderSize)); | 2320 __ mov(result, FieldOperand(result, offset + FixedArray::kHeaderSize)); |
2321 } | 2321 } |
2322 } else { | 2322 } else if (lookup.IsFound() && lookup.type() == CONSTANT_FUNCTION) { |
2323 Handle<JSFunction> function(lookup.GetConstantFunctionFromMap(*type)); | 2323 Handle<JSFunction> function(lookup.GetConstantFunctionFromMap(*type)); |
2324 __ LoadHeapObject(result, function); | 2324 __ LoadHeapObject(result, function); |
| 2325 } else { |
| 2326 // Negative lookup. |
| 2327 // Check prototypes. |
| 2328 HeapObject* current = HeapObject::cast((*type)->prototype()); |
| 2329 Heap* heap = type->GetHeap(); |
| 2330 while (current != heap->null_value()) { |
| 2331 Handle<HeapObject> link(current); |
| 2332 __ LoadHeapObject(result, link); |
| 2333 __ cmp(FieldOperand(result, HeapObject::kMapOffset), |
| 2334 Handle<Map>(JSObject::cast(current)->map())); |
| 2335 DeoptimizeIf(not_equal, env); |
| 2336 current = HeapObject::cast(current->map()->prototype()); |
| 2337 } |
| 2338 __ mov(result, factory()->undefined_value()); |
2325 } | 2339 } |
2326 } | 2340 } |
2327 | 2341 |
2328 | 2342 |
2329 void LCodeGen::EmitPushTaggedOperand(LOperand* operand) { | 2343 void LCodeGen::EmitPushTaggedOperand(LOperand* operand) { |
2330 ASSERT(!operand->IsDoubleRegister()); | 2344 ASSERT(!operand->IsDoubleRegister()); |
2331 if (operand->IsConstantOperand()) { | 2345 if (operand->IsConstantOperand()) { |
2332 Handle<Object> object = ToHandle(LConstantOperand::cast(operand)); | 2346 Handle<Object> object = ToHandle(LConstantOperand::cast(operand)); |
2333 if (object->IsSmi()) { | 2347 if (object->IsSmi()) { |
2334 __ Push(Handle<Smi>::cast(object)); | 2348 __ Push(Handle<Smi>::cast(object)); |
(...skipping 14 matching lines...) Expand all Loading... |
2349 | 2363 |
2350 int map_count = instr->hydrogen()->types()->length(); | 2364 int map_count = instr->hydrogen()->types()->length(); |
2351 bool need_generic = instr->hydrogen()->need_generic(); | 2365 bool need_generic = instr->hydrogen()->need_generic(); |
2352 | 2366 |
2353 if (map_count == 0 && !need_generic) { | 2367 if (map_count == 0 && !need_generic) { |
2354 DeoptimizeIf(no_condition, instr->environment()); | 2368 DeoptimizeIf(no_condition, instr->environment()); |
2355 return; | 2369 return; |
2356 } | 2370 } |
2357 Handle<String> name = instr->hydrogen()->name(); | 2371 Handle<String> name = instr->hydrogen()->name(); |
2358 Label done; | 2372 Label done; |
| 2373 bool compact_code = true; |
| 2374 for (int i = 0; i < map_count; ++i) { |
| 2375 LookupResult lookup(isolate()); |
| 2376 Handle<Map> map = instr->hydrogen()->types()->at(i); |
| 2377 map->LookupInDescriptors(NULL, *name, &lookup); |
| 2378 if (!lookup.IsFound() || |
| 2379 (lookup.type() != FIELD && lookup.type() != CONSTANT_FUNCTION)) { |
| 2380 // The two cases above cause a bounded amount of code to be emitted. This |
| 2381 // is not necessarily the case for other lookup results. |
| 2382 compact_code = false; |
| 2383 break; |
| 2384 } |
| 2385 } |
2359 for (int i = 0; i < map_count; ++i) { | 2386 for (int i = 0; i < map_count; ++i) { |
2360 bool last = (i == map_count - 1); | 2387 bool last = (i == map_count - 1); |
2361 Handle<Map> map = instr->hydrogen()->types()->at(i); | 2388 Handle<Map> map = instr->hydrogen()->types()->at(i); |
2362 __ cmp(FieldOperand(object, HeapObject::kMapOffset), map); | 2389 Label check_passed; |
| 2390 __ CompareMap(object, map, &check_passed, ALLOW_ELEMENT_TRANSITION_MAPS); |
2363 if (last && !need_generic) { | 2391 if (last && !need_generic) { |
2364 DeoptimizeIf(not_equal, instr->environment()); | 2392 DeoptimizeIf(not_equal, instr->environment()); |
2365 EmitLoadFieldOrConstantFunction(result, object, map, name); | 2393 __ bind(&check_passed); |
| 2394 EmitLoadFieldOrConstantFunction( |
| 2395 result, object, map, name, instr->environment()); |
2366 } else { | 2396 } else { |
2367 Label next; | 2397 Label next; |
2368 __ j(not_equal, &next, Label::kNear); | 2398 __ j(not_equal, &next, Label::kNear); |
2369 EmitLoadFieldOrConstantFunction(result, object, map, name); | 2399 __ bind(&check_passed); |
2370 __ jmp(&done, Label::kNear); | 2400 EmitLoadFieldOrConstantFunction( |
| 2401 result, object, map, name, instr->environment()); |
| 2402 __ jmp(&done, compact_code ? Label::kNear : Label::kFar); |
2371 __ bind(&next); | 2403 __ bind(&next); |
2372 } | 2404 } |
2373 } | 2405 } |
2374 if (need_generic) { | 2406 if (need_generic) { |
2375 __ mov(ecx, name); | 2407 __ mov(ecx, name); |
2376 Handle<Code> ic = isolate()->builtins()->LoadIC_Initialize(); | 2408 Handle<Code> ic = isolate()->builtins()->LoadIC_Initialize(); |
2377 CallCode(ic, RelocInfo::CODE_TARGET, instr); | 2409 CallCode(ic, RelocInfo::CODE_TARGET, instr); |
2378 } | 2410 } |
2379 __ bind(&done); | 2411 __ bind(&done); |
2380 } | 2412 } |
(...skipping 2806 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5187 FixedArray::kHeaderSize - kPointerSize)); | 5219 FixedArray::kHeaderSize - kPointerSize)); |
5188 __ bind(&done); | 5220 __ bind(&done); |
5189 } | 5221 } |
5190 | 5222 |
5191 | 5223 |
5192 #undef __ | 5224 #undef __ |
5193 | 5225 |
5194 } } // namespace v8::internal | 5226 } } // namespace v8::internal |
5195 | 5227 |
5196 #endif // V8_TARGET_ARCH_IA32 | 5228 #endif // V8_TARGET_ARCH_IA32 |
OLD | NEW |